diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b67742a --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/libndp-1.2.tar.gz diff --git a/.libndp.metadata b/.libndp.metadata new file mode 100644 index 0000000..2ae9921 --- /dev/null +++ b/.libndp.metadata @@ -0,0 +1 @@ +517136758fe773737263ba5a08398ef518b1f8b0 SOURCES/libndp-1.2.tar.gz diff --git a/SOURCES/0001-libndp-fix-cppcheck-Undefined-behavior-Variable-buf-.patch b/SOURCES/0001-libndp-fix-cppcheck-Undefined-behavior-Variable-buf-.patch new file mode 100644 index 0000000..8cd0ead --- /dev/null +++ b/SOURCES/0001-libndp-fix-cppcheck-Undefined-behavior-Variable-buf-.patch @@ -0,0 +1,41 @@ +From 4376e752c822444f1a26b5e1e974ddd7104ae15c Mon Sep 17 00:00:00 2001 +From: Jiri Pirko +Date: Wed, 18 Dec 2013 13:26:49 +0100 +Subject: [patch] libndp: fix [cppcheck] Undefined behavior: Variable 'buf' is + used as parameter and destination in s[n]printf() + +cppcheck --enable=all --inconclusive --std=posix . + +ndp_msg_opt_dnssl_domain(): + if (dom_len > len) + return NULL; + + if (strlen(buf)) +----> sprintf(buf, "%s.", buf); + buf[strlen(buf) + dom_len] = '\0'; + memcpy(buf + strlen(buf), ptr, dom_len); + +So just use strcat instead. + +Reported-by: Dan Williams +Signed-off-by: Jiri Pirko +--- + libndp/libndp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libndp/libndp.c b/libndp/libndp.c +index 0bc3fe3..e510e2e 100644 +--- a/libndp/libndp.c ++++ b/libndp/libndp.c +@@ -1540,7 +1540,7 @@ char *ndp_msg_opt_dnssl_domain(struct ndp_msg *msg, int offset, + return NULL; + + if (strlen(buf)) +- sprintf(buf, "%s.", buf); ++ strcat(buf, "."); + buf[strlen(buf) + dom_len] = '\0'; + memcpy(buf + strlen(buf), ptr, dom_len); + ptr += dom_len; +-- +1.8.4.2 + diff --git a/SOURCES/0001-libndp-validate-the-IPv6-hop-limit.patch b/SOURCES/0001-libndp-validate-the-IPv6-hop-limit.patch new file mode 100644 index 0000000..f08e854 --- /dev/null +++ b/SOURCES/0001-libndp-validate-the-IPv6-hop-limit.patch @@ -0,0 +1,142 @@ +From 5d95122c8730616b61a3febe07000a1909874ac0 Mon Sep 17 00:00:00 2001 +From: Lubomir Rintel +Date: Thu, 21 Apr 2016 19:28:29 +0200 +Subject: [PATCH 1/2] libndp: validate the IPv6 hop limit + +None of the NDP messages should ever come from a non-local network; as +stated in RFC4861's 6.1.1 (RS), 6.1.2 (RA), 7.1.1 (NS), 7.1.2 (NA), +and 8.1. (redirect): + + - The IP Hop Limit field has a value of 255, i.e., the packet + could not possibly have been forwarded by a router. + +This fixes CVE-2016-3698. + +Reported by: Julien BERNARD +Signed-off-by: Lubomir Rintel +--- + libndp/libndp.c | 49 +++++++++++++++++++++++++++++++++++++++---------- + 1 file changed, 39 insertions(+), 10 deletions(-) + +diff --git a/libndp/libndp.c b/libndp/libndp.c +index 8b7e609..2b85651 100644 +--- a/libndp/libndp.c ++++ b/libndp/libndp.c +@@ -137,7 +137,7 @@ static void *myzalloc(size_t size) + } + + static int myrecvfrom6(int sockfd, void *buf, size_t *buflen, int flags, +- struct in6_addr *addr, uint32_t *ifindex) ++ struct in6_addr *addr, uint32_t *ifindex, int *hoplimit) + { + struct sockaddr_in6 sin6; + unsigned char cbuf[CMSG_SPACE(sizeof(struct in6_pktinfo))]; +@@ -168,13 +168,26 @@ static int myrecvfrom6(int sockfd, void *buf, size_t *buflen, int flags, + *ifindex = sin6.sin6_scope_id; + for (cmsghdr = CMSG_FIRSTHDR(&msghdr); cmsghdr; + cmsghdr = CMSG_NXTHDR(&msghdr, cmsghdr)) { +- if (cmsghdr->cmsg_level == IPPROTO_IPV6 && +- cmsghdr->cmsg_type == IPV6_PKTINFO && +- cmsghdr->cmsg_len == CMSG_LEN(sizeof(struct in6_pktinfo))) { +- struct in6_pktinfo *pktinfo; ++ if (cmsghdr->cmsg_level != IPPROTO_IPV6) ++ continue; ++ ++ switch(cmsghdr->cmsg_type) { ++ case IPV6_PKTINFO: ++ if (cmsghdr->cmsg_len == CMSG_LEN(sizeof(struct in6_pktinfo))) { ++ struct in6_pktinfo *pktinfo; ++ ++ pktinfo = (struct in6_pktinfo *) CMSG_DATA(cmsghdr); ++ *ifindex = pktinfo->ipi6_ifindex; ++ } ++ break; ++ case IPV6_HOPLIMIT: ++ if (cmsghdr->cmsg_len == CMSG_LEN(sizeof(int))) { ++ int *val; + +- pktinfo = (struct in6_pktinfo *) CMSG_DATA(cmsghdr); +- *ifindex = pktinfo->ipi6_ifindex; ++ val = (int *) CMSG_DATA(cmsghdr); ++ *hoplimit = *val; ++ } ++ break; + } + } + *addr = sin6.sin6_addr; +@@ -249,6 +262,15 @@ static int ndp_sock_open(struct ndp *ndp) + goto close_sock; + } + ++ val = 1; ++ ret = setsockopt(sock, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, ++ &val, sizeof(val)); ++ if (ret == -1) { ++ err(ndp, "Failed to setsockopt IPV6_RECVHOPLIMIT,."); ++ err = -errno; ++ goto close_sock; ++ } ++ + ndp->sock = sock; + return 0; + close_sock: +@@ -291,6 +313,7 @@ struct ndp_msg { + size_t len; + struct in6_addr addrto; + uint32_t ifindex; ++ int hoplimit; + struct icmp6_hdr * icmp6_hdr; + unsigned char * opts_start; /* pointer to buf at the + place where opts start */ +@@ -1697,13 +1720,19 @@ static int ndp_sock_recv(struct ndp *ndp) + + len = ndp_msg_payload_maxlen(msg); + err = myrecvfrom6(ndp->sock, msg->buf, &len, 0, +- &msg->addrto, &msg->ifindex); ++ &msg->addrto, &msg->ifindex, &msg->hoplimit); + if (err) { + err(ndp, "Failed to receive message"); + goto free_msg; + } +- dbg(ndp, "rcvd from: %s, ifindex: %u", +- str_in6_addr(&msg->addrto), msg->ifindex); ++ dbg(ndp, "rcvd from: %s, ifindex: %u, hoplimit: %d", ++ str_in6_addr(&msg->addrto), msg->ifindex, msg->hoplimit); ++ ++ if (msg->hoplimit != 255) { ++ warn(ndp, "ignoring packet with bad hop limit (%d)", msg->hoplimit); ++ err = 0; ++ goto free_msg; ++ } + + if (len < sizeof(*msg->icmp6_hdr)) { + warn(ndp, "rcvd icmp6 packet too short (%luB)", len); +-- +2.5.5 + +From e02903973a87f57fea804162a70888ad64003844 Mon Sep 17 00:00:00 2001 +From: Lubomir Rintel +Date: Fri, 13 May 2016 16:07:59 +0200 +Subject: [PATCH] fixup! libndp: validate the IPv6 hop limit + +Actually allocate space for the hop limit. +--- + libndp/libndp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libndp/libndp.c b/libndp/libndp.c +index f817ad6..b7172fa 100644 +--- a/libndp/libndp.c ++++ b/libndp/libndp.c +@@ -140,7 +140,7 @@ static int myrecvfrom6(int sockfd, void *buf, size_t *buflen, int flags, + struct in6_addr *addr, uint32_t *ifindex, int *hoplimit) + { + struct sockaddr_in6 sin6; +- unsigned char cbuf[CMSG_SPACE(sizeof(struct in6_pktinfo))]; ++ unsigned char cbuf[2 * CMSG_SPACE(sizeof(struct in6_pktinfo))]; + struct iovec iovec; + struct msghdr msghdr; + struct cmsghdr *cmsghdr; +-- +2.5.5 + diff --git a/SOURCES/0002-libndb-reject-redirect-and-router-advertisements-fro.patch b/SOURCES/0002-libndb-reject-redirect-and-router-advertisements-fro.patch new file mode 100644 index 0000000..c73fb51 --- /dev/null +++ b/SOURCES/0002-libndb-reject-redirect-and-router-advertisements-fro.patch @@ -0,0 +1,72 @@ +From b05d91c33f5d679aa3aab190d52f9cdf3189cffb Mon Sep 17 00:00:00 2001 +From: Lubomir Rintel +Date: Thu, 21 Apr 2016 19:40:52 +0200 +Subject: [PATCH 2/2] libndb: reject redirect and router advertisements from + non-link-local + +RFC4861 suggests that these messages should only originate from +link-local addresses in 6.1.2 (RA) and 8.1. (redirect): + +Mitigates CVE-2016-3698. + +Signed-off-by: Lubomir Rintel +--- + libndp/libndp.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/libndp/libndp.c b/libndp/libndp.c +index 2b85651..f817ad6 100644 +--- a/libndp/libndp.c ++++ b/libndp/libndp.c +@@ -333,6 +333,7 @@ struct ndp_msg_type_info { + uint8_t raw_type; + size_t raw_struct_size; + void (*addrto_adjust)(struct in6_addr *addr); ++ bool (*addrto_validate)(struct in6_addr *addr); + }; + + static void ndp_msg_addrto_adjust_all_nodes(struct in6_addr *addr) +@@ -359,6 +360,11 @@ static void ndp_msg_addrto_adjust_all_routers(struct in6_addr *addr) + addr->s6_addr32[3] = htonl(0x2); + } + ++static bool ndp_msg_addrto_validate_link_local(struct in6_addr *addr) ++{ ++ return IN6_IS_ADDR_LINKLOCAL (addr); ++} ++ + static struct ndp_msg_type_info ndp_msg_type_info_list[] = + { + [NDP_MSG_RS] = { +@@ -371,6 +377,7 @@ static struct ndp_msg_type_info ndp_msg_type_info_list[] = + .strabbr = "RA", + .raw_type = ND_ROUTER_ADVERT, + .raw_struct_size = sizeof(struct nd_router_advert), ++ .addrto_validate = ndp_msg_addrto_validate_link_local, + }, + [NDP_MSG_NS] = { + .strabbr = "NS", +@@ -387,6 +394,7 @@ static struct ndp_msg_type_info ndp_msg_type_info_list[] = + .strabbr = "R", + .raw_type = ND_REDIRECT, + .raw_struct_size = sizeof(struct nd_redirect), ++ .addrto_validate = ndp_msg_addrto_validate_link_local, + }, + }; + +@@ -418,7 +426,11 @@ static bool ndp_msg_check_valid(struct ndp_msg *msg) + + if (len < ndp_msg_type_info(msg_type)->raw_struct_size) + return false; +- return true; ++ ++ if (ndp_msg_type_info(msg_type)->addrto_validate) ++ return ndp_msg_type_info(msg_type)->addrto_validate(&msg->addrto); ++ else ++ return true; + } + + static struct ndp_msg *ndp_msg_alloc(void) +-- +2.5.5 + diff --git a/SOURCES/0003-libndp-add-option-flags-to-send-messages.patch b/SOURCES/0003-libndp-add-option-flags-to-send-messages.patch new file mode 100644 index 0000000..c2f8999 --- /dev/null +++ b/SOURCES/0003-libndp-add-option-flags-to-send-messages.patch @@ -0,0 +1,210 @@ +From cb1ab5fc8b993f23924385ebee42d52ff45e4e8a Mon Sep 17 00:00:00 2001 +From: Jamie Bainbridge +Date: Thu, 10 Mar 2016 16:12:05 +1000 +Subject: [PATCH 3/6] libndp: add option flags to send messages + +Within NA and RA message types, there are flags such as Solicited and Override +(RFC-4861 Section 4). RA flags are currently implemented but not NA flags, so +add remaining NA flag getters/setters. + +Set Solicited/Override flag on NA when appropriate, add a flags interface to +the send API, and implement ability to send Unsolicited NA. + +Signed-off-by: Jamie Bainbridge +Signed-off-by: Jiri Pirko +--- + include/ndp.h | 13 ++++++- + libndp/libndp.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- + 2 files changed, 124 insertions(+), 3 deletions(-) + +diff --git a/include/ndp.h b/include/ndp.h +index 4ca33b8..09b234f 100644 +--- a/include/ndp.h ++++ b/include/ndp.h +@@ -53,6 +53,9 @@ enum ndp_msg_type { + NDP_MSG_ALL, /* Matches all */ + }; + ++#define ND_OPT_NORMAL 0x0000 /* default, no change to ND message */ ++#define ND_OPT_NA_UNSOL 0x0001 /* Unsolicited Neighbour Advertisement */ ++ + enum ndp_route_preference { + NDP_ROUTE_PREF_LOW = 3, + NDP_ROUTE_PREF_MEDIUM = 0, +@@ -76,7 +79,7 @@ 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); +-int ndp_msg_send(struct ndp *ndp, struct ndp_msg *msg); ++int ndp_msg_send(struct ndp *ndp, struct ndp_msg *msg, uint8_t flags); + + uint8_t ndp_msgra_curhoplimit(struct ndp_msgra *msgra); + void ndp_msgra_curhoplimit_set(struct ndp_msgra *msgra, uint8_t curhoplimit); +@@ -100,6 +103,14 @@ uint32_t ndp_msgra_retransmit_time(struct ndp_msgra *msgra); + void ndp_msgra_retransmit_time_set(struct ndp_msgra *msgra, + uint32_t retransmit_time); + ++bool ndp_msgna_flag_router(struct ndp_msgna *msgna); ++void ndp_msgna_flag_router_set(struct ndp_msgna *msgna, bool flag_router); ++bool ndp_msgna_flag_solicited(struct ndp_msgna *msgna); ++void ndp_msgna_flag_solicited_set(struct ndp_msgna *msgna, ++ bool flag_solicited); ++bool ndp_msgna_flag_override(struct ndp_msgna *msgna); ++void ndp_msgna_flag_override_set(struct ndp_msgna *msgna, bool flag_override); ++ + enum ndp_msg_opt_type { + NDP_MSG_OPT_SLLADDR, /* Source Link-layer Address */ + NDP_MSG_OPT_TLLADDR, /* Target Link-layer Address */ +diff --git a/libndp/libndp.c b/libndp/libndp.c +index e75f4f7..899c2b0 100644 +--- a/libndp/libndp.c ++++ b/libndp/libndp.c +@@ -676,7 +676,7 @@ struct in6_addr *ndp_msg_addrto(struct ndp_msg *msg) + * + * Get interface index of message. + * +- * Returns: Inteface index ++ * Returns: Interface index + **/ + NDP_EXPORT + uint32_t ndp_msg_ifindex(struct ndp_msg *msg) +@@ -700,18 +700,34 @@ void ndp_msg_ifindex_set(struct ndp_msg *msg, uint32_t ifindex) + * ndp_msg_send: + * @ndp: libndp library context + * @msg: message structure ++ * @flags: option flags within message type + * + * Send message. + * + * Returns: zero on success or negative number in case of an error. + **/ + NDP_EXPORT +-int ndp_msg_send(struct ndp *ndp, struct ndp_msg *msg) ++int ndp_msg_send(struct ndp *ndp, struct ndp_msg *msg, uint8_t flags) + { + enum ndp_msg_type msg_type = ndp_msg_type(msg); + + if (ndp_msg_type_info(msg_type)->addrto_adjust) + ndp_msg_type_info(msg_type)->addrto_adjust(&msg->addrto); ++ ++ switch (msg_type) { ++ case NDP_MSG_NA: ++ if (flags & ND_OPT_NA_UNSOL) { ++ ndp_msgna_flag_override_set((struct ndp_msgna*)&msg->nd_msg, true); ++ ndp_msgna_flag_solicited_set((struct ndp_msgna*)&msg->nd_msg, false); ++ ndp_msg_addrto_adjust_all_nodes(&msg->addrto); ++ } else { ++ ndp_msgna_flag_solicited_set((struct ndp_msgna*)&msg->nd_msg, true); ++ } ++ break; ++ default: ++ break; ++ } ++ + return mysendto6(ndp->sock, msg->buf, msg->len, 0, + &msg->addrto, msg->ifindex); + } +@@ -958,6 +974,100 @@ void ndp_msgra_retransmit_time_set(struct ndp_msgra *msgra, + + + /** ++ * SECTION: msgna getters/setters ++ * @short_description: Getters and setters for NA message ++ */ ++ ++/** ++ * ndp_msgna_flag_router: ++ * @msgna: NA message structure ++ * ++ * Get NA router flag. ++ * ++ * Returns: router flag. ++ **/ ++NDP_EXPORT ++bool ndp_msgna_flag_router(struct ndp_msgna *msgna) ++{ ++ return msgna->na->nd_na_flags_reserved & ND_NA_FLAG_ROUTER; ++} ++ ++/** ++ * ndp_msgna_flag_router_set: ++ * @msgna: NA message structure ++ * ++ * Set NA router flag. ++ **/ ++NDP_EXPORT ++void ndp_msgna_flag_router_set(struct ndp_msgna *msgna, bool flag_router) ++{ ++ if (flag_router) ++ msgna->na->nd_na_flags_reserved |= ND_NA_FLAG_ROUTER; ++ else ++ msgna->na->nd_na_flags_reserved &= ~ND_NA_FLAG_ROUTER; ++} ++ ++/** ++ * ndp_msgna_flag_solicited: ++ * @msgna: NA message structure ++ * ++ * Get NA solicited flag. ++ * ++ * Returns: solicited flag. ++ **/ ++NDP_EXPORT ++bool ndp_msgna_flag_solicited(struct ndp_msgna *msgna) ++{ ++ return msgna->na->nd_na_flags_reserved & ND_NA_FLAG_SOLICITED; ++} ++ ++/** ++ * ndp_msgna_flag_solicited_set: ++ * @msgna: NA message structure ++ * ++ * Set NA managed flag. ++ **/ ++NDP_EXPORT ++void ndp_msgna_flag_solicited_set(struct ndp_msgna *msgna, bool flag_solicited) ++{ ++ if (flag_solicited) ++ msgna->na->nd_na_flags_reserved |= ND_NA_FLAG_SOLICITED; ++ else ++ msgna->na->nd_na_flags_reserved &= ~ND_NA_FLAG_SOLICITED; ++} ++ ++/** ++ * ndp_msgna_flag_override: ++ * @msgna: NA message structure ++ * ++ * Get NA override flag. ++ * ++ * Returns: override flag. ++ **/ ++NDP_EXPORT ++bool ndp_msgna_flag_override(struct ndp_msgna *msgna) ++{ ++ return msgna->na->nd_na_flags_reserved & ND_NA_FLAG_OVERRIDE; ++} ++ ++/** ++ * ndp_msgna_flag_override_set: ++ * @msgra: NA message structure ++ * ++ * Set NA override flag. ++ */ ++ ++NDP_EXPORT ++void ndp_msgna_flag_override_set(struct ndp_msgna *msgna, bool flag_override) ++{ ++ if (flag_override) ++ msgna->na->nd_na_flags_reserved |= ND_NA_FLAG_OVERRIDE; ++ else ++ msgna->na->nd_na_flags_reserved &= ~ND_NA_FLAG_OVERRIDE; ++} ++ ++ ++/** + * SECTION: msg_opt infrastructure + * @short_description: Infrastructure for options + */ +-- +2.5.5 + diff --git a/SOURCES/0004-ndptool-add-option-to-send-messages-types.patch b/SOURCES/0004-ndptool-add-option-to-send-messages-types.patch new file mode 100644 index 0000000..d65a397 --- /dev/null +++ b/SOURCES/0004-ndptool-add-option-to-send-messages-types.patch @@ -0,0 +1,92 @@ +From 8bd97d7548236a29deeca27c94feb94a1cc71149 Mon Sep 17 00:00:00 2001 +From: Jamie Bainbridge +Date: Thu, 10 Mar 2016 16:12:06 +1000 +Subject: [PATCH 4/6] ndptool: add option to send messages types + +Use the new flags interface of message sending, implement sending +Unsolicited NA in ndptool. -U was chosen to mirror established +convention of unsolicited ARP in arping. + +Signed-off-by: Jamie Bainbridge +Signed-off-by: Jiri Pirko +--- + man/ndptool.8 | 4 ++++ + utils/ndptool.c | 12 ++++++++++-- + 2 files changed, 14 insertions(+), 2 deletions(-) + +diff --git a/man/ndptool.8 b/man/ndptool.8 +index b742683..ef765dc 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 "\-U, \-\-unsolicited" ++Send Unsolicited NA. ++ + .SH COMMAND + .TP + .B "monitor" +diff --git a/utils/ndptool.c b/utils/ndptool.c +index 04ec4e1..2639f81 100644 +--- a/utils/ndptool.c ++++ b/utils/ndptool.c +@@ -39,6 +39,8 @@ enum verbosity_level { + #define DEFAULT_VERB VERB1 + static int g_verbosity = DEFAULT_VERB; + ++static uint8_t flags = ND_OPT_NORMAL; ++ + #define pr_err(args...) fprintf(stderr, ##args) + #define pr_outx(verb_level, args...) \ + do { \ +@@ -133,6 +135,7 @@ static void print_help(const char *argv0) { + "\t-t --msg-type=TYPE Specify message type\n" + "\t (\"rs\", \"ra\", \"ns\", \"na\")\n" + "\t-i --ifname=IFNAME Specify interface name\n" ++ "\t-U --unsolicited Send Unsolicited NA\n" + "Available commands:\n" + "\tmonitor\n" + "\tsend\n", +@@ -340,7 +343,8 @@ static int run_cmd_send(struct ndp *ndp, enum ndp_msg_type msg_type, + return err; + } + ndp_msg_ifindex_set(msg, ifindex); +- err = ndp_msg_send(ndp, msg); ++ ++ err = ndp_msg_send(ndp, msg, flags); + if (err) { + pr_err("Failed to send message\n"); + goto msg_destroy; +@@ -379,6 +383,7 @@ int main(int argc, char **argv) + { "verbose", no_argument, NULL, 'v' }, + { "msg-type", required_argument, NULL, 't' }, + { "ifname", required_argument, NULL, 'i' }, ++ { "unsolicited",no_argument, NULL, 'U' }, + { NULL, 0, NULL, 0 } + }; + int opt; +@@ -391,7 +396,7 @@ int main(int argc, char **argv) + int err; + int res = EXIT_FAILURE; + +- while ((opt = getopt_long(argc, argv, "hvt:i:", ++ while ((opt = getopt_long(argc, argv, "hvt:i:U", + long_options, NULL)) >= 0) { + + switch(opt) { +@@ -409,6 +414,9 @@ int main(int argc, char **argv) + free(ifname); + ifname = strdup(optarg); + break; ++ case 'U': ++ flags |= ND_OPT_NA_UNSOL; ++ break; + case '?': + pr_err("unknown option.\n"); + print_help(argv0); +-- +2.5.5 + diff --git a/SOURCES/0005-libndp-fix-type-of-field-na-in-struct-ndp_msgna.patch b/SOURCES/0005-libndp-fix-type-of-field-na-in-struct-ndp_msgna.patch new file mode 100644 index 0000000..47f92fc --- /dev/null +++ b/SOURCES/0005-libndp-fix-type-of-field-na-in-struct-ndp_msgna.patch @@ -0,0 +1,37 @@ +From d0ea3eccf42e4cec59b057474f844fc4f616d4de Mon Sep 17 00:00:00 2001 +From: Thomas Haller +Date: Thu, 10 Mar 2016 10:16:05 +0100 +Subject: [PATCH 5/6] libndp: fix type of field "na" in "struct ndp_msgna" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Otherwise, compilation fails since commit cb1ab5fc8b: + + libndp.c: In function ‘ndp_msgna_flag_router’: + libndp.c:992:18: error: ‘struct nd_neighbor_solicit’ has no member named ‘nd_na_hdr’ + return msgna->na->nd_na_flags_reserved & ND_NA_FLAG_ROUTER; + +Fixes: dfed476eee ("lib: setup first pointer in all type-specific structures at once") +Signed-off-by: Thomas Haller +Signed-off-by: Jiri Pirko +--- + libndp/libndp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libndp/libndp.c b/libndp/libndp.c +index 899c2b0..ed72658 100644 +--- a/libndp/libndp.c ++++ b/libndp/libndp.c +@@ -278,7 +278,7 @@ struct ndp_msgns { + }; + + struct ndp_msgna { +- struct nd_neighbor_solicit *na; /* must be first */ ++ struct nd_neighbor_advert *na; /* must be first */ + }; + + struct ndp_msgr { +-- +2.5.5 + diff --git a/SOURCES/0006-libndp-revert-API-change-for-ndp_msg_send-and-add-nd.patch b/SOURCES/0006-libndp-revert-API-change-for-ndp_msg_send-and-add-nd.patch new file mode 100644 index 0000000..253f22b --- /dev/null +++ b/SOURCES/0006-libndp-revert-API-change-for-ndp_msg_send-and-add-nd.patch @@ -0,0 +1,80 @@ +From 9be7e45d57d7c65d01c15819df0e864b25275dbe Mon Sep 17 00:00:00 2001 +From: Thomas Haller +Date: Thu, 10 Mar 2016 11:55:54 +0100 +Subject: [PATCH 6/6] libndp: revert API change for ndp_msg_send() and add + ndp_msg_send_with_flags() + +Fixes: cb1ab5fc8b ("libndp: add option flags to send messages") +Signed-off-by: Thomas Haller +Signed-off-by: Jiri Pirko +--- + include/ndp.h | 3 ++- + libndp/libndp.c | 17 ++++++++++++++++- + utils/ndptool.c | 2 +- + 3 files changed, 19 insertions(+), 3 deletions(-) + +diff --git a/include/ndp.h b/include/ndp.h +index 09b234f..0dc1468 100644 +--- a/include/ndp.h ++++ b/include/ndp.h +@@ -79,7 +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); +-int ndp_msg_send(struct ndp *ndp, struct ndp_msg *msg, uint8_t flags); ++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); + + uint8_t ndp_msgra_curhoplimit(struct ndp_msgra *msgra); + void ndp_msgra_curhoplimit_set(struct ndp_msgra *msgra, uint8_t curhoplimit); +diff --git a/libndp/libndp.c b/libndp/libndp.c +index ed72658..8b7e609 100644 +--- a/libndp/libndp.c ++++ b/libndp/libndp.c +@@ -700,6 +700,21 @@ void ndp_msg_ifindex_set(struct ndp_msg *msg, uint32_t ifindex) + * ndp_msg_send: + * @ndp: libndp library context + * @msg: message structure ++ * ++ * Send message. ++ * ++ * Returns: zero on success or negative number in case of an error. ++ **/ ++NDP_EXPORT ++int ndp_msg_send(struct ndp *ndp, struct ndp_msg *msg) ++{ ++ return ndp_msg_send_with_flags(ndp, msg, ND_OPT_NORMAL); ++} ++ ++/** ++ * ndp_msg_send_with_flags: ++ * @ndp: libndp library context ++ * @msg: message structure + * @flags: option flags within message type + * + * Send message. +@@ -707,7 +722,7 @@ void ndp_msg_ifindex_set(struct ndp_msg *msg, uint32_t ifindex) + * Returns: zero on success or negative number in case of an error. + **/ + NDP_EXPORT +-int ndp_msg_send(struct ndp *ndp, struct ndp_msg *msg, uint8_t flags) ++int ndp_msg_send_with_flags(struct ndp *ndp, struct ndp_msg *msg, uint8_t flags) + { + enum ndp_msg_type msg_type = ndp_msg_type(msg); + +diff --git a/utils/ndptool.c b/utils/ndptool.c +index 2639f81..1d96f4c 100644 +--- a/utils/ndptool.c ++++ b/utils/ndptool.c +@@ -344,7 +344,7 @@ static int run_cmd_send(struct ndp *ndp, enum ndp_msg_type msg_type, + } + ndp_msg_ifindex_set(msg, ifindex); + +- err = ndp_msg_send(ndp, msg, flags); ++ err = ndp_msg_send_with_flags(ndp, msg, flags); + if (err) { + pr_err("Failed to send message\n"); + goto msg_destroy; +-- +2.5.5 + diff --git a/SOURCES/0007-ndptool-add-T-target-support.patch b/SOURCES/0007-ndptool-add-T-target-support.patch new file mode 100644 index 0000000..cca7567 --- /dev/null +++ b/SOURCES/0007-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 7/8] 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/0008-ndptool-fix-target-parameter-typo.patch b/SOURCES/0008-ndptool-fix-target-parameter-typo.patch new file mode 100644 index 0000000..27bedb9 --- /dev/null +++ b/SOURCES/0008-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 8/8] 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/0009-libndp-close-sockfd-after-using-to-avoid-handle-leak.patch b/SOURCES/0009-libndp-close-sockfd-after-using-to-avoid-handle-leak.patch new file mode 100644 index 0000000..31e0007 --- /dev/null +++ b/SOURCES/0009-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 9/9] 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/SPECS/libndp.spec b/SPECS/libndp.spec new file mode 100644 index 0000000..a0dafc3 --- /dev/null +++ b/SPECS/libndp.spec @@ -0,0 +1,121 @@ +Name: libndp +Version: 1.2 +Release: 9%{?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 + +Patch0: 0001-libndp-fix-cppcheck-Undefined-behavior-Variable-buf-.patch +Patch1: 0001-libndp-validate-the-IPv6-hop-limit.patch +Patch2: 0002-libndb-reject-redirect-and-router-advertisements-fro.patch +Patch3: 0003-libndp-add-option-flags-to-send-messages.patch +Patch4: 0004-ndptool-add-option-to-send-messages-types.patch +Patch5: 0005-libndp-fix-type-of-field-na-in-struct-ndp_msgna.patch +Patch6: 0006-libndp-revert-API-change-for-ndp_msg_send-and-add-nd.patch +Patch7: 0007-ndptool-add-T-target-support.patch +Patch8: 0008-ndptool-fix-target-parameter-typo.patch +Patch9: 0009-libndp-close-sockfd-after-using-to-avoid-handle-leak.patch + +%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} + +%description devel +The libndp-devel package contains the header files and libraries +necessary for developing programs using libndp. + +%prep +%setup -q +%patch0 -p1 -b .fix_cppcheck_var_buf +%patch1 -p1 -b .hop-limit +%patch2 -p1 -b .link-local +%patch3 -p1 -b .flags-to-send-msgs +%patch4 -p1 -b .opts-to-send-msgs-types +%patch5 -p1 -b .fix-type-of-na +%patch6 -p1 -b .revert-api-change-for-ndp_msg_send +%patch7 -p1 -b .support-target-for-ns +%patch8 -p1 -b .fix-target-parameter-typo +%patch9 -p1 -b .close-sockfd-after-using + +%build +%configure --disable-static +make %{?_smp_mflags} + +%install +make install DESTDIR=$RPM_BUILD_ROOT INSTALL="install -p" +find $RPM_BUILD_ROOT -name \*.la -delete + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + +%files +%doc COPYING +%{_libdir}/*so.* +%{_bindir}/ndptool +%{_mandir}/man8/ndptool.8* + +%files devel +%{_includedir}/* +%{_libdir}/*.so +%{_libdir}/pkgconfig/*.pc + +%changelog +* Tue Dec 18 2018 Hangbin Liu - 1.2-8 +- ndptool: add -T target support +- ndptool: fix target parameter typo + +* Tue May 17 2016 Eric Garver - 1.2-7 +- libndp: add option flags to send messages +- ndptool: add option to send messages types +- libndp: fix type of field "na" in "struct ndp_msgna" +- libndp: revert API change for ndp_msg_send() and add + +* Sat May 14 2016 Lubomir Rintel - 1.2-6 +- libndp: fix hop limit validation [CVE-2016-3698] + +* Fri May 06 2016 Lubomir Rintel - 1.2-5 +- libndp: validate the IPv6 hop limit [CVE-2016-3698] +- libndb: reject redirect and router advertisements from non-link-local [CVE-2016-3698] + +* Fri Jan 24 2014 Daniel Mach - 1.2-4 +- Mass rebuild 2014-01-24 + +* Tue Jan 21 2014 Jiri Pirko - 1.2-3 +- libndp: fix [cppcheck] Undefined behavior: Variable 'buf' is used as parameter and destination in s[n]printf() [1044084] + +* Fri Dec 27 2013 Daniel Mach - 1.2-2 +- Mass rebuild 2013-12-27 + +* Tue Oct 15 2013 Jiri Pirko - 1.2-1 +- Update to 1.2 +- libndp: silently ignore packets with optlen 0 [1016064] +- libndp: fix processing for larger options [1016064] +- libndp: do not fail on receiving non-ndp packets [1016078] + +* Fri Sep 13 2013 Dan Williams - 1.0-2 +- Fix .pc file includes path +- Fix ndptool -v argument + +* Thu Aug 08 2013 Jiri Pirko - 1.0-1 +- Update to 1.0 + +* Sat Aug 03 2013 Fedora Release Engineering - 0.1-4.20130723git873037a +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* Wed Jul 24 2013 Dan Williams - 0.1-3.20130723git873037a +- Update to git 873037a + +* Fri Jun 07 2013 Jiri Pirko - 0.1-2.20130607git39e1f53 +- Update to git 39e1f53 + +* Sat May 04 2013 Jiri Pirko - 0.1-1.20130504gitca3c399 +- Initial build.