From 10e3b0b2fd2a9913da9e33db23e7c8d2868bc3c4 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Apr 28 2020 09:40:37 +0000 Subject: import libndp-1.7-3.el8 --- diff --git a/SOURCES/0001-ndptool-add-T-target-support.patch b/SOURCES/0001-ndptool-add-T-target-support.patch new file mode 100644 index 0000000..eecb1fc --- /dev/null +++ b/SOURCES/0001-ndptool-add-T-target-support.patch @@ -0,0 +1,292 @@ +From acccd780df517b0e5925de4497688b6238bee10c Mon Sep 17 00:00:00 2001 +From: Hangbin Liu +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 +Signed-off-by: Jiri Pirko +--- + 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 + #include + #include ++#include ++#include + + #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 + diff --git a/SOURCES/0002-ndptool-fix-target-parameter-typo.patch b/SOURCES/0002-ndptool-fix-target-parameter-typo.patch new file mode 100644 index 0000000..cd5771d --- /dev/null +++ b/SOURCES/0002-ndptool-fix-target-parameter-typo.patch @@ -0,0 +1,31 @@ +From e67999b18c59d37d59b557316dfe53ed5d52e923 Mon Sep 17 00:00:00 2001 +From: Hangbin Liu +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 +Signed-off-by: Jiri Pirko +--- + 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 + diff --git a/SOURCES/0003-libndp-close-sockfd-after-using-to-avoid-handle-leak.patch b/SOURCES/0003-libndp-close-sockfd-after-using-to-avoid-handle-leak.patch new file mode 100644 index 0000000..2c1d0cb --- /dev/null +++ b/SOURCES/0003-libndp-close-sockfd-after-using-to-avoid-handle-leak.patch @@ -0,0 +1,53 @@ +From 81df977dc0c2a04d5fa0c18dee130490d84a92f5 Mon Sep 17 00:00:00 2001 +From: Hangbin Liu +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 +Signed-off-by: Jiri Pirko +--- + 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 + diff --git a/SOURCES/0004-libndp-fix-nd_msg-typo-when-setting-target-address.patch b/SOURCES/0004-libndp-fix-nd_msg-typo-when-setting-target-address.patch new file mode 100644 index 0000000..16e9500 --- /dev/null +++ b/SOURCES/0004-libndp-fix-nd_msg-typo-when-setting-target-address.patch @@ -0,0 +1,39 @@ +From 23490cbf50a9ad62d480a0916c6d0ca61d221afb Mon Sep 17 00:00:00 2001 +From: Hangbin Liu +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 +Signed-off-by: Jiri Pirko +--- + 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 + diff --git a/SOURCES/0005-ndptool-add-D-dest-support.patch b/SOURCES/0005-ndptool-add-D-dest-support.patch new file mode 100644 index 0000000..bda1968 --- /dev/null +++ b/SOURCES/0005-ndptool-add-D-dest-support.patch @@ -0,0 +1,248 @@ +From e9a35fba03ec3670586fba7debd2e0cb3cd4341e Mon Sep 17 00:00:00 2001 +From: Hangbin Liu +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 +Signed-off-by: Jiri Pirko +--- + 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 + diff --git a/SOURCES/0006-ndptool-fix-potential-memory-leak-caused-by-strdup.patch b/SOURCES/0006-ndptool-fix-potential-memory-leak-caused-by-strdup.patch new file mode 100644 index 0000000..b7cb54c --- /dev/null +++ b/SOURCES/0006-ndptool-fix-potential-memory-leak-caused-by-strdup.patch @@ -0,0 +1,56 @@ +From 27403f898372e99b0ad916bebe2bc29e95bee1f0 Mon Sep 17 00:00:00 2001 +From: Hangbin Liu +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 +Signed-off-by: Jiri Pirko +--- + 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 + diff --git a/SPECS/libndp.spec b/SPECS/libndp.spec index 3eb173d..dfd36a4 100644 --- a/SPECS/libndp.spec +++ b/SPECS/libndp.spec @@ -1,12 +1,19 @@ Name: libndp Version: 1.7 -Release: 1%{?dist} +Release: 3%{?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 + %description This package contains a library which provides a wrapper for IPv6 Neighbor Discovery Protocol. It also provides a tool @@ -23,6 +30,12 @@ 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 %build %configure --disable-static @@ -48,6 +61,16 @@ find $RPM_BUILD_ROOT -name \*.la -delete %{_libdir}/pkgconfig/*.pc %changelog +* Fri Nov 01 2019 Hangbin Liu - 1.7-3 +- ndptool: add -D dest support (rhbz 1697595) +- ndptool: fix potential memory leak caused by strdup (rhbz 1697595) + +* Fri Nov 01 2019 Hangbin Liu - 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) + * Thu Jul 18 2019 Hangbin Liu - 1.7-1 - Update to 1.7 - libndp: apply filter to raw socket to only accept ND messages