Compare commits

...

No commits in common. "c8" and "b32418427bf3ecd62f9f8056d0d410afc892deca" have entirely different histories.

15 changed files with 217 additions and 917 deletions

11
.gitignore vendored
View File

@ -1 +1,10 @@
SOURCES/libndp-1.7.tar.gz
/libndp-20130504gitca3c399.tar.gz
/libndp-20130607git39e1f53.tar.gz
/libndp-1.0.tar.gz
/libndp-1.2.tar.gz
/libndp-1.3.tar.gz
/libndp-1.4.tar.gz
/libndp-1.5.tar.gz
/libndp-1.6.tar.gz
/libndp-1.7.tar.gz
/libndp-1.8.tar.gz

View File

@ -1 +1 @@
db9a37a8d363134484771f85b938280a41029ad2 SOURCES/libndp-1.7.tar.gz
c3a63a27574a0af9a893a395a4916314bb596292 libndp-1.8.tar.gz

View File

@ -1,292 +0,0 @@
From acccd780df517b0e5925de4497688b6238bee10c Mon Sep 17 00:00:00 2001
From: Hangbin Liu <haliu@redhat.com>
Date: Mon, 6 Aug 2018 22:02:09 +0800
Subject: [PATCH 01/04] ndptool: add -T target support
Currently ndptool can send a Neighbour Solicitation, but does not target
an IP address, so the NS packet doesn't really make sense.
Extend ndptool to target a destination for Neighbour Solicitation.
v2:
1) remove function ipv6_addr_is_multicast()
2) inline some help functions.
3) update code style.
4) rename parameter -d/--dest to -T/--target
Signed-off-by: Hangbin Liu <haliu@redhat.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
include/ndp.h | 2 +
libndp/libndp.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++++
man/ndptool.8 | 4 ++
utils/ndptool.c | 21 +++++++--
4 files changed, 145 insertions(+), 3 deletions(-)
diff --git a/include/ndp.h b/include/ndp.h
index 0dc1468..698bba7 100644
--- a/include/ndp.h
+++ b/include/ndp.h
@@ -79,6 +79,8 @@ enum ndp_msg_type ndp_msg_type(struct ndp_msg *msg);
struct in6_addr *ndp_msg_addrto(struct ndp_msg *msg);
uint32_t ndp_msg_ifindex(struct ndp_msg *msg);
void ndp_msg_ifindex_set(struct ndp_msg *msg, uint32_t ifindex);
+void ndp_msg_target_set(struct ndp_msg *msg, struct in6_addr *target);
+void ndp_msg_opt_set(struct ndp_msg *msg);
int ndp_msg_send(struct ndp *ndp, struct ndp_msg *msg);
int ndp_msg_send_with_flags(struct ndp *ndp, struct ndp_msg *msg, uint8_t flags);
diff --git a/libndp/libndp.c b/libndp/libndp.c
index baacb76..bec55d4 100644
--- a/libndp/libndp.c
+++ b/libndp/libndp.c
@@ -32,10 +32,14 @@
#include <net/ethernet.h>
#include <assert.h>
#include <ndp.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
#include "ndp_private.h"
#include "list.h"
+#define pr_err(args...) fprintf(stderr, ##args)
+
/**
* SECTION: logging
* @short_description: libndp logging facility
@@ -308,6 +312,23 @@ static void ndp_msg_addrto_adjust_all_routers(struct in6_addr *addr)
addr->s6_addr32[3] = htonl(0x2);
}
+/*
+ * compute link-local solicited-node multicast address
+ */
+static void ndp_msg_addrto_adjust_solicit_multi(struct in6_addr *addr,
+ struct in6_addr *target)
+{
+ struct in6_addr any = IN6ADDR_ANY_INIT;
+
+ /* Don't set addr to target if target is default IN6ADDR_ANY_INIT */
+ if (!memcmp(target, &any, sizeof(any)))
+ return;
+ addr->s6_addr32[0] = htonl(0xFF020000);
+ addr->s6_addr32[1] = 0;
+ addr->s6_addr32[2] = htonl(0x1);
+ addr->s6_addr32[3] = htonl(0xFF000000) | target->s6_addr32[3];
+}
+
static bool ndp_msg_addrto_validate_link_local(struct in6_addr *addr)
{
return IN6_IS_ADDR_LINKLOCAL (addr);
@@ -679,6 +700,106 @@ void ndp_msg_ifindex_set(struct ndp_msg *msg, uint32_t ifindex)
msg->ifindex = ifindex;
}
+/**
+ * ndp_msg_target_set:
+ * @msg: message structure
+ * @target: ns,na target
+ *
+ * Set target address for NS and NA.
+ **/
+NDP_EXPORT
+void ndp_msg_target_set(struct ndp_msg *msg, struct in6_addr *target)
+{
+ enum ndp_msg_type msg_type = ndp_msg_type(msg);
+ switch (msg_type) {
+ case NDP_MSG_NS:
+ ((struct ndp_msgna*)&msg->nd_msg)->na->nd_na_target = *target;
+ /*
+ * Neighbor Solicitations are multicast when the node
+ * needs to resolve an address and unicast when the
+ * node seeks to verify the reachability of a
+ * neighbor.
+ *
+ * In this case we don't know if we have a cache of
+ * target, so we use multicast to resolve the target
+ * address.
+ * */
+ ndp_msg_addrto_adjust_solicit_multi(&msg->addrto, target);
+ break;
+ case NDP_MSG_NA:
+ ((struct ndp_msgns*)&msg->nd_msg)->ns->nd_ns_target = *target;
+ break;
+ default:
+ break;
+ }
+}
+
+static int ndp_get_iface_mac(int ifindex, char *ptr)
+{
+ int sockfd;
+ struct ifreq ifr;
+
+ sockfd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (sockfd == -1) {
+ pr_err("%s: Failed to create socket", __func__);
+ return -errno;
+ }
+
+ if (if_indextoname(ifindex, (char *)&ifr.ifr_name) == NULL) {
+ pr_err("%s: Failed to get iface name with index %d", __func__, ifindex);
+ return -errno;
+ }
+
+ if (ioctl(sockfd, SIOCGIFHWADDR, &ifr) < 0) {
+ pr_err("%s: Failed to get iface mac with index %d\n", __func__, ifindex);
+ return -errno;
+ }
+
+ memcpy(ptr, &ifr.ifr_hwaddr.sa_data, sizeof(ifr.ifr_hwaddr.sa_data));
+
+ return 0;
+}
+
+static void ndp_msg_opt_set_linkaddr(struct ndp_msg *msg, int ndp_opt)
+{
+ char *opts_start = ndp_msg_payload_opts(msg);
+ struct nd_opt_hdr *s_laddr_opt = (struct nd_opt_hdr *) opts_start;
+ char *opt_data = (char *) s_laddr_opt + sizeof(struct nd_opt_hdr);
+ int err;
+
+ err = ndp_get_iface_mac(ndp_msg_ifindex(msg), opt_data);
+ if (err)
+ return;
+
+ opt_data += 6;
+ s_laddr_opt->nd_opt_type = ndp_opt;
+ s_laddr_opt->nd_opt_len = (opt_data - opts_start) >> 3;
+ msg->len += opt_data - opts_start;
+}
+
+/**
+ * ndp_msg_opt_set:
+ * @msg: message structure
+ *
+ * Set neighbor discovery option info.
+ **/
+NDP_EXPORT
+void ndp_msg_opt_set(struct ndp_msg *msg)
+{
+ enum ndp_msg_type msg_type = ndp_msg_type(msg);
+
+ switch (msg_type) {
+ case NDP_MSG_NS:
+ ndp_msg_opt_set_linkaddr(msg, ND_OPT_SOURCE_LINKADDR);
+ break;
+ case NDP_MSG_NA:
+ ndp_msg_opt_set_linkaddr(msg, ND_OPT_TARGET_LINKADDR);
+ break;
+ default:
+ break;
+ }
+}
+
/**
* ndp_msg_send:
* @ndp: libndp library context
diff --git a/man/ndptool.8 b/man/ndptool.8
index ef765dc..dd6ddee 100644
--- a/man/ndptool.8
+++ b/man/ndptool.8
@@ -41,6 +41,10 @@ Neighbor Advertisement.
.B "\-i ifname, \-\-ifname ifname"
Specified interface name.
+.TP
+.B "\-T target, \-\-target target"
+Specified target address for NS/NA message.
+
.TP
.B "\-U, \-\-unsolicited"
Send Unsolicited NA.
diff --git a/utils/ndptool.c b/utils/ndptool.c
index 96479fa..ba24d75 100644
--- a/utils/ndptool.c
+++ b/utils/ndptool.c
@@ -135,6 +135,7 @@ static void print_help(const char *argv0) {
"\t-v --verbose Increase output verbosity\n"
"\t-t --msg-type=TYPE Specify message type\n"
"\t (\"rs\", \"ra\", \"ns\", \"na\")\n"
+ "\t-T --target=TARGET Target address for NS or NA\n"
"\t-i --ifname=IFNAME Specify interface name\n"
"\t-U --unsolicited Send Unsolicited NA\n"
"Available commands:\n"
@@ -333,7 +334,7 @@ static int run_cmd_monitor(struct ndp *ndp, enum ndp_msg_type msg_type,
}
static int run_cmd_send(struct ndp *ndp, enum ndp_msg_type msg_type,
- uint32_t ifindex)
+ uint32_t ifindex, struct in6_addr *target)
{
struct ndp_msg *msg;
int err;
@@ -344,6 +345,8 @@ static int run_cmd_send(struct ndp *ndp, enum ndp_msg_type msg_type,
return err;
}
ndp_msg_ifindex_set(msg, ifindex);
+ ndp_msg_target_set(msg, target);
+ ndp_msg_opt_set(msg);
err = ndp_msg_send_with_flags(ndp, msg, flags);
if (err) {
@@ -384,6 +387,7 @@ int main(int argc, char **argv)
{ "verbose", no_argument, NULL, 'v' },
{ "msg-type", required_argument, NULL, 't' },
{ "ifname", required_argument, NULL, 'i' },
+ { "target", required_argument, NULL, 'T' },
{ "unsolicited",no_argument, NULL, 'U' },
{ NULL, 0, NULL, 0 }
};
@@ -392,12 +396,14 @@ int main(int argc, char **argv)
char *msgtypestr = NULL;
enum ndp_msg_type msg_type;
char *ifname = NULL;
+ char *addr = NULL;
+ struct in6_addr target = IN6ADDR_ANY_INIT;
uint32_t ifindex;
char *cmd_name;
int err;
int res = EXIT_FAILURE;
- while ((opt = getopt_long(argc, argv, "hvt:i:U",
+ while ((opt = getopt_long(argc, argv, "hvt:T:i:U",
long_options, NULL)) >= 0) {
switch(opt) {
@@ -415,6 +421,10 @@ int main(int argc, char **argv)
free(ifname);
ifname = strdup(optarg);
break;
+ case 'd':
+ free(addr);
+ addr = strdup(optarg);
+ break;
case 'U':
flags |= ND_OPT_NA_UNSOL;
break;
@@ -448,6 +458,11 @@ int main(int argc, char **argv)
}
}
+ if (addr && inet_pton(AF_INET6, addr, &target) <= 0) {
+ pr_err("Invalid target address \"%s\"\n", addr);
+ goto errout;
+ }
+
err = get_msg_type(&msg_type, msgtypestr);
if (err) {
pr_err("Invalid message type \"%s\" selected\n", msgtypestr);
@@ -478,7 +493,7 @@ int main(int argc, char **argv)
print_help(argv0);
goto errout;
}
- err = run_cmd_send(ndp, msg_type, ifindex);
+ err = run_cmd_send(ndp, msg_type, ifindex, &target);
} else {
pr_err("Unknown command \"%s\"\n", cmd_name);
goto ndp_close;
--
2.19.2

View File

@ -1,31 +0,0 @@
From e67999b18c59d37d59b557316dfe53ed5d52e923 Mon Sep 17 00:00:00 2001
From: Hangbin Liu <haliu@redhat.com>
Date: Wed, 12 Dec 2018 11:38:30 +0800
Subject: [PATCH 02/04] ndptool: fix target parameter typo
In my last commit acccd780df517 ("ndptool: add -T target support"), after
renaming parameter -d to -T. I forgot to change the name in switch opt.
Fixes: acccd780df517 ("ndptool: add -T target support")
Signed-off-by: Hangbin Liu <haliu@redhat.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
utils/ndptool.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/utils/ndptool.c b/utils/ndptool.c
index ba24d75..afa516f 100644
--- a/utils/ndptool.c
+++ b/utils/ndptool.c
@@ -421,7 +421,7 @@ int main(int argc, char **argv)
free(ifname);
ifname = strdup(optarg);
break;
- case 'd':
+ case 'T':
free(addr);
addr = strdup(optarg);
break;
--
2.19.2

View File

@ -1,53 +0,0 @@
From 81df977dc0c2a04d5fa0c18dee130490d84a92f5 Mon Sep 17 00:00:00 2001
From: Hangbin Liu <haliu@redhat.com>
Date: Thu, 20 Dec 2018 11:48:16 +0800
Subject: [PATCH 03/04] libndp: close sockfd after using to avoid handle leak
Fixes: acccd780df517 ("ndptool: add -T target support")
Signed-off-by: Hangbin Liu <haliu@redhat.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
libndp/libndp.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/libndp/libndp.c b/libndp/libndp.c
index bec55d4..f327d45 100644
--- a/libndp/libndp.c
+++ b/libndp/libndp.c
@@ -736,7 +736,7 @@ void ndp_msg_target_set(struct ndp_msg *msg, struct in6_addr *target)
static int ndp_get_iface_mac(int ifindex, char *ptr)
{
- int sockfd;
+ int sockfd, err = 0;
struct ifreq ifr;
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
@@ -747,17 +747,21 @@ static int ndp_get_iface_mac(int ifindex, char *ptr)
if (if_indextoname(ifindex, (char *)&ifr.ifr_name) == NULL) {
pr_err("%s: Failed to get iface name with index %d", __func__, ifindex);
- return -errno;
+ err = -errno;
+ goto close_sock;
}
if (ioctl(sockfd, SIOCGIFHWADDR, &ifr) < 0) {
pr_err("%s: Failed to get iface mac with index %d\n", __func__, ifindex);
- return -errno;
+ err = -errno;
+ goto close_sock;
}
memcpy(ptr, &ifr.ifr_hwaddr.sa_data, sizeof(ifr.ifr_hwaddr.sa_data));
- return 0;
+close_sock:
+ close(sockfd);
+ return err;
}
static void ndp_msg_opt_set_linkaddr(struct ndp_msg *msg, int ndp_opt)
--
2.19.2

View File

@ -1,39 +0,0 @@
From 23490cbf50a9ad62d480a0916c6d0ca61d221afb Mon Sep 17 00:00:00 2001
From: Hangbin Liu <haliu@redhat.com>
Date: Mon, 2 Sep 2019 19:39:36 +0800
Subject: [PATCH 04/04] libndp: fix nd_msg typo when setting target address
When setting the target address of nd_msg, I set the ns/na type reversed.
Fixes: acccd780df517 ("ndptool: add -T target support")
Signed-off-by: Hangbin Liu <haliu@redhat.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
libndp/libndp.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libndp/libndp.c b/libndp/libndp.c
index f327d45..8b7de6b 100644
--- a/libndp/libndp.c
+++ b/libndp/libndp.c
@@ -713,7 +713,7 @@ void ndp_msg_target_set(struct ndp_msg *msg, struct in6_addr *target)
enum ndp_msg_type msg_type = ndp_msg_type(msg);
switch (msg_type) {
case NDP_MSG_NS:
- ((struct ndp_msgna*)&msg->nd_msg)->na->nd_na_target = *target;
+ ((struct ndp_msgns*)&msg->nd_msg)->ns->nd_ns_target = *target;
/*
* Neighbor Solicitations are multicast when the node
* needs to resolve an address and unicast when the
@@ -727,7 +727,7 @@ void ndp_msg_target_set(struct ndp_msg *msg, struct in6_addr *target)
ndp_msg_addrto_adjust_solicit_multi(&msg->addrto, target);
break;
case NDP_MSG_NA:
- ((struct ndp_msgns*)&msg->nd_msg)->ns->nd_ns_target = *target;
+ ((struct ndp_msgna*)&msg->nd_msg)->na->nd_na_target = *target;
break;
default:
break;
--
2.19.2

View File

@ -1,248 +0,0 @@
From e9a35fba03ec3670586fba7debd2e0cb3cd4341e Mon Sep 17 00:00:00 2001
From: Hangbin Liu <haliu@redhat.com>
Date: Mon, 2 Sep 2019 19:39:12 +0800
Subject: [PATCH 05/06] ndptool: add -D dest support
This patch add -D dest option, with this option a user could set the dest
address in IPv6 header for solicited NS/NA message
For function ndp_msg_addrto_adjust_solicit_multi(), I moved the check
in ndp_msg_target_set() instead of in the function itself.
I also use reverse christmas tree variable order in the main() function
of ndptool.c.
Signed-off-by: Hangbin Liu <haliu@redhat.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
include/ndp.h | 1 +
libndp/libndp.c | 42 ++++++++++++++++++++++++++++++++----------
man/ndptool.8 | 6 +++++-
utils/ndptool.c | 49 +++++++++++++++++++++++++++++++++++--------------
4 files changed, 73 insertions(+), 25 deletions(-)
diff --git a/include/ndp.h b/include/ndp.h
index 698bba7..7bf8794 100644
--- a/include/ndp.h
+++ b/include/ndp.h
@@ -80,6 +80,7 @@ struct in6_addr *ndp_msg_addrto(struct ndp_msg *msg);
uint32_t ndp_msg_ifindex(struct ndp_msg *msg);
void ndp_msg_ifindex_set(struct ndp_msg *msg, uint32_t ifindex);
void ndp_msg_target_set(struct ndp_msg *msg, struct in6_addr *target);
+void ndp_msg_dest_set(struct ndp_msg *msg, struct in6_addr *dest);
void ndp_msg_opt_set(struct ndp_msg *msg);
int ndp_msg_send(struct ndp *ndp, struct ndp_msg *msg);
int ndp_msg_send_with_flags(struct ndp *ndp, struct ndp_msg *msg, uint8_t flags);
diff --git a/libndp/libndp.c b/libndp/libndp.c
index 8b7de6b..283de77 100644
--- a/libndp/libndp.c
+++ b/libndp/libndp.c
@@ -318,11 +318,6 @@ static void ndp_msg_addrto_adjust_all_routers(struct in6_addr *addr)
static void ndp_msg_addrto_adjust_solicit_multi(struct in6_addr *addr,
struct in6_addr *target)
{
- struct in6_addr any = IN6ADDR_ANY_INIT;
-
- /* Don't set addr to target if target is default IN6ADDR_ANY_INIT */
- if (!memcmp(target, &any, sizeof(any)))
- return;
addr->s6_addr32[0] = htonl(0xFF020000);
addr->s6_addr32[1] = 0;
addr->s6_addr32[2] = htonl(0x1);
@@ -700,17 +695,41 @@ void ndp_msg_ifindex_set(struct ndp_msg *msg, uint32_t ifindex)
msg->ifindex = ifindex;
}
+/**
+ * ndp_msg_dest_set:
+ * @msg: message structure
+ * @dest: ns,na dest
+ *
+ * Set dest address in IPv6 header for NS and NA.
+ **/
+NDP_EXPORT
+void ndp_msg_dest_set(struct ndp_msg *msg, struct in6_addr *dest)
+{
+ enum ndp_msg_type msg_type = ndp_msg_type(msg);
+ switch (msg_type) {
+ case NDP_MSG_NS:
+ /* fall through */
+ case NDP_MSG_NA:
+ msg->addrto = *dest;
+ /* fall through */
+ default:
+ break;
+ }
+}
+
/**
* ndp_msg_target_set:
* @msg: message structure
* @target: ns,na target
*
- * Set target address for NS and NA.
+ * Set target address in ICMPv6 header for NS and NA.
**/
NDP_EXPORT
void ndp_msg_target_set(struct ndp_msg *msg, struct in6_addr *target)
{
+ struct in6_addr any = IN6ADDR_ANY_INIT;
enum ndp_msg_type msg_type = ndp_msg_type(msg);
+
switch (msg_type) {
case NDP_MSG_NS:
((struct ndp_msgns*)&msg->nd_msg)->ns->nd_ns_target = *target;
@@ -720,11 +739,14 @@ void ndp_msg_target_set(struct ndp_msg *msg, struct in6_addr *target)
* node seeks to verify the reachability of a
* neighbor.
*
- * In this case we don't know if we have a cache of
- * target, so we use multicast to resolve the target
- * address.
+ * In this case we need to update the dest address in
+ * IPv6 header when
+ * a) IPv6 dest address is not set
+ * b) ICMPv6 target address is supplied
* */
- ndp_msg_addrto_adjust_solicit_multi(&msg->addrto, target);
+ if (!memcmp(&msg->addrto, &any, sizeof(any)) &&
+ memcmp(target, &any, sizeof(any)))
+ ndp_msg_addrto_adjust_solicit_multi(&msg->addrto, target);
break;
case NDP_MSG_NA:
((struct ndp_msgna*)&msg->nd_msg)->na->nd_na_target = *target;
diff --git a/man/ndptool.8 b/man/ndptool.8
index dd6ddee..fb0dd63 100644
--- a/man/ndptool.8
+++ b/man/ndptool.8
@@ -41,9 +41,13 @@ Neighbor Advertisement.
.B "\-i ifname, \-\-ifname ifname"
Specified interface name.
+.TP
+.B "\-D dest, \-\-dest dest"
+Specified dest address in IPv6 header for NS/NA message.
+
.TP
.B "\-T target, \-\-target target"
-Specified target address for NS/NA message.
+Specified target address in ICMPv6 header for NS/NA message.
.TP
.B "\-U, \-\-unsolicited"
diff --git a/utils/ndptool.c b/utils/ndptool.c
index afa516f..1131462 100644
--- a/utils/ndptool.c
+++ b/utils/ndptool.c
@@ -135,7 +135,8 @@ static void print_help(const char *argv0) {
"\t-v --verbose Increase output verbosity\n"
"\t-t --msg-type=TYPE Specify message type\n"
"\t (\"rs\", \"ra\", \"ns\", \"na\")\n"
- "\t-T --target=TARGET Target address for NS or NA\n"
+ "\t-D --dest=DEST Dest address in IPv6 header for NS or NA\n"
+ "\t-T --target=TARGET Target address in ICMPv6 header for NS or NA\n"
"\t-i --ifname=IFNAME Specify interface name\n"
"\t-U --unsolicited Send Unsolicited NA\n"
"Available commands:\n"
@@ -334,7 +335,8 @@ static int run_cmd_monitor(struct ndp *ndp, enum ndp_msg_type msg_type,
}
static int run_cmd_send(struct ndp *ndp, enum ndp_msg_type msg_type,
- uint32_t ifindex, struct in6_addr *target)
+ uint32_t ifindex, struct in6_addr *dest,
+ struct in6_addr *target)
{
struct ndp_msg *msg;
int err;
@@ -345,6 +347,7 @@ static int run_cmd_send(struct ndp *ndp, enum ndp_msg_type msg_type,
return err;
}
ndp_msg_ifindex_set(msg, ifindex);
+ ndp_msg_dest_set(msg, dest);
ndp_msg_target_set(msg, target);
ndp_msg_opt_set(msg);
@@ -387,23 +390,27 @@ int main(int argc, char **argv)
{ "verbose", no_argument, NULL, 'v' },
{ "msg-type", required_argument, NULL, 't' },
{ "ifname", required_argument, NULL, 'i' },
+ { "dest", required_argument, NULL, 'D' },
{ "target", required_argument, NULL, 'T' },
{ "unsolicited",no_argument, NULL, 'U' },
{ NULL, 0, NULL, 0 }
};
- int opt;
- struct ndp *ndp;
- char *msgtypestr = NULL;
+
+ struct in6_addr target = IN6ADDR_ANY_INIT;
+ struct in6_addr dest = IN6ADDR_ANY_INIT;
enum ndp_msg_type msg_type;
+ char *msgtypestr = NULL;
+ int res = EXIT_FAILURE;
char *ifname = NULL;
- char *addr = NULL;
- struct in6_addr target = IN6ADDR_ANY_INIT;
+ char *daddr = NULL;
+ char *taddr = NULL;
uint32_t ifindex;
+ struct ndp *ndp;
char *cmd_name;
+ int opt;
int err;
- int res = EXIT_FAILURE;
- while ((opt = getopt_long(argc, argv, "hvt:T:i:U",
+ while ((opt = getopt_long(argc, argv, "hvt:D:T:i:U",
long_options, NULL)) >= 0) {
switch(opt) {
@@ -421,9 +428,13 @@ int main(int argc, char **argv)
free(ifname);
ifname = strdup(optarg);
break;
+ case 'D':
+ free(daddr);
+ daddr = strdup(optarg);
+ break;
case 'T':
- free(addr);
- addr = strdup(optarg);
+ free(taddr);
+ taddr = strdup(optarg);
break;
case 'U':
flags |= ND_OPT_NA_UNSOL;
@@ -458,8 +469,18 @@ int main(int argc, char **argv)
}
}
- if (addr && inet_pton(AF_INET6, addr, &target) <= 0) {
- pr_err("Invalid target address \"%s\"\n", addr);
+ if (daddr && (flags & ND_OPT_NA_UNSOL)) {
+ pr_err("Conflicts for both setting dest address and unsolicited flag\n");
+ goto errout;
+ }
+
+ if (daddr && inet_pton(AF_INET6, daddr, &dest) <= 0) {
+ pr_err("Invalid dest address \"%s\"\n", daddr);
+ goto errout;
+ }
+
+ if (taddr && inet_pton(AF_INET6, taddr, &target) <= 0) {
+ pr_err("Invalid target address \"%s\"\n", taddr);
goto errout;
}
@@ -493,7 +514,7 @@ int main(int argc, char **argv)
print_help(argv0);
goto errout;
}
- err = run_cmd_send(ndp, msg_type, ifindex, &target);
+ err = run_cmd_send(ndp, msg_type, ifindex, &dest, &target);
} else {
pr_err("Unknown command \"%s\"\n", cmd_name);
goto ndp_close;
--
2.19.2

View File

@ -1,56 +0,0 @@
From 27403f898372e99b0ad916bebe2bc29e95bee1f0 Mon Sep 17 00:00:00 2001
From: Hangbin Liu <haliu@redhat.com>
Date: Tue, 24 Sep 2019 14:17:56 +0800
Subject: [PATCH 06/06] ndptool: fix potential memory leak caused by strdup
We use strdup to copy the parameters. As strdup will call malloc when
obtain the memory, we need to free them before exit, or there will be
memory leak. This is found by covscan.
Signed-off-by: Hangbin Liu <haliu@redhat.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
utils/ndptool.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/utils/ndptool.c b/utils/ndptool.c
index 1131462..4eca83d 100644
--- a/utils/ndptool.c
+++ b/utils/ndptool.c
@@ -416,7 +416,8 @@ int main(int argc, char **argv)
switch(opt) {
case 'h':
print_help(argv0);
- return EXIT_SUCCESS;
+ res = EXIT_SUCCESS;
+ goto errout;
case 'v':
g_verbosity++;
break;
@@ -442,11 +443,11 @@ int main(int argc, char **argv)
case '?':
pr_err("unknown option.\n");
print_help(argv0);
- return EXIT_FAILURE;
+ goto errout;
default:
pr_err("unknown option \"%c\".\n", opt);
print_help(argv0);
- return EXIT_FAILURE;
+ goto errout;
}
}
@@ -530,5 +531,9 @@ int main(int argc, char **argv)
ndp_close:
ndp_close(ndp);
errout:
+ free(msgtypestr);
+ free(ifname);
+ free(daddr);
+ free(taddr);
return res;
}
--
2.19.2

View File

@ -1,152 +0,0 @@
From 682b0ccabdc7970f89544c0d19477515583a5f5b Mon Sep 17 00:00:00 2001
From: Beniamino Galvani <bgalvani@redhat.com>
Date: Thu, 25 Feb 2021 14:38:16 +0100
Subject: [PATCH] libndp,ndptool: use poll() instead of select()
select() doesn't support file descriptors greater than 1023. If the
program has many files open, the socket descriptor can be > 1023 and
then FD_SET(fd, &rfds) causes a buffer overflow.
Switch to poll() and ppoll() which don't have this limitation.
Signed-off-by: Beniamino Galvani <bgalvani@redhat.com>
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
libndp/libndp.c | 20 +++++++++-----------
utils/Makefile.am | 2 +-
utils/Makefile.in | 2 +-
utils/ndptool.c | 22 +++++++++-------------
4 files changed, 20 insertions(+), 26 deletions(-)
diff --git a/libndp/libndp.c b/libndp/libndp.c
index 06a3d23..6314717 100644
--- a/libndp/libndp.c
+++ b/libndp/libndp.c
@@ -25,7 +25,7 @@
#include <errno.h>
#include <ctype.h>
#include <sys/socket.h>
-#include <sys/select.h>
+#include <poll.h>
#include <netinet/in.h>
#include <netinet/icmp6.h>
#include <arpa/inet.h>
@@ -2107,22 +2107,20 @@ int ndp_call_eventfd_handler(struct ndp *ndp)
NDP_EXPORT
int ndp_callall_eventfd_handler(struct ndp *ndp)
{
- fd_set rfds;
- int fdmax;
- struct timeval tv;
- int fd = ndp_get_eventfd(ndp);
+ struct pollfd pfd;
int ret;
int err;
- memset(&tv, 0, sizeof(tv));
- FD_ZERO(&rfds);
- FD_SET(fd, &rfds);
- fdmax = fd + 1;
+ pfd = (struct pollfd) {
+ .fd = ndp_get_eventfd(ndp),
+ .events = POLLIN,
+ };
+
while (true) {
- ret = select(fdmax, &rfds, NULL, NULL, &tv);
+ ret = poll(&pfd, 1, 0);
if (ret == -1)
return -errno;
- if (!FD_ISSET(fd, &rfds))
+ if (!(pfd.revents & POLLIN))
return 0;
err = ndp_call_eventfd_handler(ndp);
if (err)
diff --git a/utils/Makefile.am b/utils/Makefile.am
index cca00c2..75e452c 100644
--- a/utils/Makefile.am
+++ b/utils/Makefile.am
@@ -2,7 +2,7 @@ MAINTAINERCLEANFILES = Makefile.in
ACLOCAL_AMFLAGS = -I m4
-AM_CFLAGS = -I${top_srcdir}/include
+AM_CFLAGS = -I${top_srcdir}/include -D_GNU_SOURCE
ndptool_LDADD = $(top_builddir)/libndp/libndp.la
diff --git a/utils/Makefile.in b/utils/Makefile.in
index e339b19..d81de50 100644
--- a/utils/Makefile.in
+++ b/utils/Makefile.in
@@ -294,7 +294,7 @@ top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
MAINTAINERCLEANFILES = Makefile.in
ACLOCAL_AMFLAGS = -I m4
-AM_CFLAGS = -I${top_srcdir}/include
+AM_CFLAGS = -I${top_srcdir}/include -D_GNU_SOURCE
ndptool_LDADD = $(top_builddir)/libndp/libndp.la
ndptool_SOURCES = ndptool.c
all: all-am
diff --git a/utils/ndptool.c b/utils/ndptool.c
index 662ff01..618f167 100644
--- a/utils/ndptool.c
+++ b/utils/ndptool.c
@@ -28,7 +28,7 @@
#include <arpa/inet.h>
#include <errno.h>
#include <ndp.h>
-#include <sys/select.h>
+#include <poll.h>
enum verbosity_level {
VERB1,
@@ -59,13 +59,10 @@ static void empty_signal_handler(int signal)
static int run_main_loop(struct ndp *ndp)
{
- fd_set rfds;
- fd_set rfds_tmp;
- int fdmax;
+ struct pollfd pfd;
int ret;
struct sigaction siginfo;
sigset_t mask;
- int ndp_fd;
int err = 0;
sigemptyset(&siginfo.sa_mask);
@@ -100,23 +97,22 @@ static int run_main_loop(struct ndp *ndp)
sigemptyset(&mask);
- FD_ZERO(&rfds);
- ndp_fd = ndp_get_eventfd(ndp);
- FD_SET(ndp_fd, &rfds);
- fdmax = ndp_fd + 1;
+ pfd = (struct pollfd) {
+ .fd = ndp_get_eventfd(ndp),
+ .events = POLLIN,
+ };
for (;;) {
- rfds_tmp = rfds;
- ret = pselect(fdmax, &rfds_tmp, NULL, NULL, NULL, &mask);
+ ret = ppoll(&pfd, 1, NULL, &mask);
if (ret == -1) {
if (errno == EINTR) {
goto out;
}
- pr_err("Select failed\n");
+ pr_err("Poll failed\n");
err = -errno;
goto out;
}
- if (FD_ISSET(ndp_fd, &rfds_tmp)) {
+ if (pfd.revents & POLLIN) {
err = ndp_call_eventfd_handler(ndp);
if (err) {
pr_err("ndp eventfd handler call failed\n");
--
2.26.2

6
gating.yaml Normal file
View File

@ -0,0 +1,6 @@
--- !Policy
product_versions:
- rhel-9
decision_context: osci_compose_gate
rules:
- !PassingTestCaseRule {test_case_name: desktop-qe.desktop-ci.tier1-gating.functional}

View File

@ -1,27 +1,19 @@
Name: libndp
Version: 1.7
Release: 6%{?dist}
Version: 1.8
Release: 4%{?dist}
Summary: Library for Neighbor Discovery Protocol
Group: System Environment/Libraries
License: LGPLv2+
URL: http://www.libndp.org/
Source: http://www.libndp.org/files/libndp-%{version}.tar.gz
Patch1: 0001-ndptool-add-T-target-support.patch
Patch2: 0002-ndptool-fix-target-parameter-typo.patch
Patch3: 0003-libndp-close-sockfd-after-using-to-avoid-handle-leak.patch
Patch4: 0004-libndp-fix-nd_msg-typo-when-setting-target-address.patch
Patch5: 0005-ndptool-add-D-dest-support.patch
Patch6: 0006-ndptool-fix-potential-memory-leak-caused-by-strdup.patch
Patch7: 0007-libndp-ndptool-use-poll-instead-of-select.patch
BuildRequires: gcc
BuildRequires: make
%description
This package contains a library which provides a wrapper
for IPv6 Neighbor Discovery Protocol. It also provides a tool
named ndptool for sending and receiving NDP messages.
%package devel
Group: Development/Libraries
Summary: Libraries and header files for libndp development
Requires: libndp = %{version}-%{release}
@ -31,13 +23,6 @@ necessary for developing programs using libndp.
%prep
%setup -q
%patch1 -p1 -b .ndptool_add_T_target_support
%patch2 -p1 -b .ndptool_fix_target_parameter_typo
%patch3 -p1 -b .libndp_close_sockfd_after_using
%patch4 -p1 -b .libndp_fix_nd_msg_typo
%patch5 -p1 -b .ndptool_add_D_dest_support
%patch6 -p1 -b .ndptool_fix_potential_memory_leak
%patch7 -p1 -b .ndptool_use_poll
%build
%configure --disable-static
@ -47,9 +32,7 @@ make %{?_smp_mflags}
make install DESTDIR=$RPM_BUILD_ROOT INSTALL="install -p"
find $RPM_BUILD_ROOT -name \*.la -delete
%post -p /sbin/ldconfig
%postun -p /sbin/ldconfig
%ldconfig_scriptlets
%files
%doc COPYING
@ -63,37 +46,58 @@ find $RPM_BUILD_ROOT -name \*.la -delete
%{_libdir}/pkgconfig/*.pc
%changelog
* Mon Apr 26 2021 Hangbin Liu <haliu@redhat.com> - 1.7-6
- Bump the version number due to conflict with (rhbz 1937721)
* Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 1.8-4
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
Related: rhbz#1991688
* Fri Mar 12 2021 Hangbin Liu <haliu@redhat.com> - 1.7-5
- Bump the version number due to conflict with (rhbz 1937721)
* Tue Jun 1 2021 Hangbin Liu <haliu@redhat.com> - 1.8-3
- Update tcpreplay version in OSCI gating tests (rhbz#1958933)
* Fri Mar 05 2021 Hangbin Liu <haliu@redhat.com> - 1.7-4
- libndp,ndptool: use poll() instead of select (rhbz 1933041)
* Wed May 26 2021 Hangbin Liu <haliu@redhat.com> - 1.8-2
- Add OSCI gating tests (rhbz#1958933)
* Fri Nov 01 2019 Hangbin Liu <haliu@redhat.com> - 1.7-3
- ndptool: add -D dest support (rhbz 1697595)
- ndptool: fix potential memory leak caused by strdup (rhbz 1697595)
* Fri May 21 2021 Hangbin Liu <haliu@redhat.com> - 1.8-1
- 1.8 release (rhbz#1958933)
- libndp,ndptool: use poll() instead of select()
- libndp: avoid static buffer for debug string in ndp_sock_recv()
- ndptool: avoid static buffer for string in ndptool
- libndp: use thread local variables for static return arguments
- ndptool: don't use static variable for local context in msgrcv_handler_func()
- ndptool: fix printing dnssl lifetime in ndptool
- ndptool: fix potential memory leak caused by strdup
- ndptool: add -D dest support
- libndp: fix nd_msg typo when setting target address
- libndp: close sockfd after using to avoid handle leak
- ndptool: fix target parameter typo
- ndptool: add -T target support
* Fri Nov 01 2019 Hangbin Liu <haliu@redhat.com> - 1.7-2
- ndptool: add -T target support (rhbz 1666194)
- ndptool: fix target parameter typo (rhbz 1666194)
- libndp: close sockfd after using to avoid handle leak (rhbz 1666194)
- libndp: fix nd_msg typo when setting target address (rhbz 1666194)
* Fri Apr 16 2021 Mohan Boddu <mboddu@redhat.com> - 1.7-8
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
* Thu Jul 18 2019 Hangbin Liu <haliu@redhat.com> - 1.7-1
- Update to 1.7
* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 1.7-7
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
* Tue Jul 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1.7-6
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
* Wed Jan 29 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1.7-5
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
* Thu Jul 25 2019 Fedora Release Engineering <releng@fedoraproject.org> - 1.7-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
* Fri Feb 01 2019 Fedora Release Engineering <releng@fedoraproject.org> - 1.7-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
* Fri Jul 13 2018 Fedora Release Engineering <releng@fedoraproject.org> - 1.7-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
* Fri Jun 08 2018 Jiri Pirko <jiri@mellanox.com> - 1.7-1
- 1.7 release
- libndp: apply filter to raw socket to only accept ND messages
- libndp: move ndp_sock_{open,close}() after msg parsing functions
- ndptool: Fix compilation on musl libc
* Tue Jul 16 2019 Hangbin Liu <haliu@redhat.com> - 1.6-7
- Add libndp gating test (rhbz 1682325)
* Fri Sep 28 2018 Eric Garver <egarver@redhat.com> - 1.6-6
- Rebuilt for annocheck fixes (rhbz 1630584)
* Wed Feb 07 2018 Fedora Release Engineering <releng@fedoraproject.org> - 1.6-5
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild

1
sources Normal file
View File

@ -0,0 +1 @@
SHA512 (libndp-1.8.tar.gz) = bce17095f01eb9df6601a2ff0597b0373f4b0005b1edac8c085e4c9d54f9cd18f08faf1604624e0e0992be66fa6f22a71106af46bc73c9e326663c7cf0c5a7fd

BIN
tests/basic/nd.pcap Normal file

Binary file not shown.

134
tests/basic/send_monitor_nd.sh Executable file
View File

@ -0,0 +1,134 @@
#!/bin/sh
ret=0
nsuccess=0
nfail=0
NETNS_0="ns-$(mktemp -u XXXXXX)"
NETNS_1="ns-$(mktemp -u XXXXXX)"
# $1: return value
# $2: log message
libndp_log() {
local rc=$1
local msg="$2"
if [ $rc -eq 0 ]; then
printf "[libndp gating]: %-30s [ PASS ]\n" "$msg"
nsuccess=$((nsuccess+1))
else
printf "[libndp gating]: %-30s [ FAIL ]\n" "$msg"
nfail=$((nfail+1)) && ret=1
fi
}
install_tcpreplay() {
which tcpreplay && return 0
local ver="4.3.4"
wget https://github.com/appneta/tcpreplay/releases/download/v${ver}/tcpreplay-${ver}.tar.xz
tar xf tcpreplay-${ver}.tar.xz
cd tcpreplay-${ver}
./configure && make && make install
cd ../
which tcpreplay
}
clean_up() {
ip netns del ${NETNS_0} &> /dev/null
ip netns del ${NETNS_1} &> /dev/null
ip link del veth0 &> /dev/null
ip link del veth1 &> /dev/null
}
trap clean_up EXIT
setup() {
install_tcpreplay &> tcpreplay.log || \
{ libndp_log $? "Install tcpreplay" && cat tcpreplay.log; return 1; }
clean_up
ip netns add "${NETNS_0}"
ip netns add "${NETNS_1}"
ip -netns "${NETNS_0}" link set lo up
ip -netns "${NETNS_1}" link set lo up
ip link add type veth
ip link set veth0 netns "${NETNS_0}"
ip link set veth1 netns "${NETNS_1}"
ip -netns "${NETNS_0}" link set veth0 addr 00:00:00:00:00:01
ip -netns "${NETNS_1}" link set veth1 addr 00:00:00:00:00:02
ip -netns "${NETNS_0}" link set veth0 up
ip -netns "${NETNS_1}" link set veth1 up
}
monitor_nd()
{
ip netns exec "${NETNS_1}" unbuffer ndptool -i veth1 monitor &> monitor.log &
sleep 2
# TODO: maybe fuzz the pcap file and see if ndptool still works
ip netns exec "${NETNS_0}" tcpreplay -l 2 -i veth0 nd.pcap
sleep 2 && kill -9 $!
grep -q "Type: NS" monitor.log; libndp_log $? "Monitor NS"
grep -q "Type: NA" monitor.log; libndp_log $? "Monitor NA"
# commit this due to bug 1082933
# grep -q "Type: RS" monitor.log; libndp_log $? "Monitor RS"
grep -q "Type: RA" monitor.log; libndp_log $? "Monitor RA"
# TODO: add ICMPv6 redirect support
}
send_nd()
{
ip netns exec "${NETNS_1}" tcpdump -i veth1 -nn -l &> rs.log &
sleep 2
ip netns exec "${NETNS_0}" ndptool -i veth0 -t rs send
sleep 2 && kill -9 $!
#ip netns exec "${NETNS_0}" ndptool -i veth0 -t ra send
ip netns exec "${NETNS_1}" tcpdump -i veth1 -nn -l &> ns.log &
sleep 2
ip netns exec "${NETNS_0}" ndptool -i veth0 -t ns send
sleep 2 && kill -9 $!
ip netns exec "${NETNS_1}" tcpdump -i veth1 -nn -l &> ns_t.log &
sleep 2
ip netns exec "${NETNS_0}" ndptool -i veth0 -t ns -T fe80::200:ff:fe00:2 send
sleep 2 && kill -9 $!
#ip netns exec "${NETNS_0}" ndptool -i veth0 -t na send
ip netns exec "${NETNS_1}" tcpdump -i veth1 -nn -l &> na_d_t.log &
sleep 2
ip netns exec "${NETNS_0}" ndptool -i veth0 -t na -D fe80::200:ff:fe00:2 -T fe80::200:ff:fe00:1 send
sleep 2 && kill -9 $!
ip netns exec "${NETNS_1}" tcpdump -i veth1 -nn -l &> na_u.log &
sleep 2
ip netns exec "${NETNS_0}" ndptool -i veth0 -U -t na send
sleep 2 && kill -9 $!
grep -q "fe80::200:ff:fe00:1 > ff02::2: ICMP6, router solicitation" rs.log; libndp_log $? "Send RS"
grep -q "fe80::200:ff:fe00:1 > ff02::1: ICMP6, neighbor solicitation, who has ::" ns.log; libndp_log $? "Send NS"
grep -q "fe80::200:ff:fe00:1 > ff02::1:ff00:2: ICMP6, neighbor solicitation, who has fe80::200:ff:fe00:2" ns_t.log; libndp_log $? "Send NS with target"
grep -q "fe80::200:ff:fe00:1 > fe80::200:ff:fe00:2: ICMP6, neighbor advertisement, tgt is fe80::200:ff:fe00:1" na_d_t.log; libndp_log $? "Send NA with dest and target"
grep -q "fe80::200:ff:fe00:1 > ff02::1: ICMP6, neighbor advertisement, tgt is ::" na_u.log; libndp_log $? "Send unsolicited NA"
}
setup || exit 1
monitor_nd
send_nd
printf "\nTests passed: %3d\n" ${nsuccess}
printf "Tests failed: %3d\n" ${nfail}
if [ ${nfail} -ne 0 ]; then
echo -e "\nDEBUG INFO:\n"
for log in `ls *.log`; do
echo "# cat $log"
cat $log
done
fi
exit $ret

17
tests/tests.yml Normal file
View File

@ -0,0 +1,17 @@
# Tests for libndp
- hosts: localhost
roles:
- role: standard-test-basic
required_packages:
- expect
- gcc
- libpcap-devel
- make
- tcpdump
- wget
tags:
- classic
tests:
- sanity-tests:
dir: basic
run: sh send_monitor_nd.sh