Gentoo Archives: gentoo-commits

From: Jeroen Roovers <jer@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] repo/gentoo:master commit in: dev-libs/libdnet/files/, dev-libs/libdnet/
Date: Sun, 27 Sep 2020 10:07:02
Message-Id: 1601201214.af1632be53234f09ff25a70576f4f98a782d405a.jer@gentoo
1 commit: af1632be53234f09ff25a70576f4f98a782d405a
2 Author: Jeroen Roovers <jer <AT> gentoo <DOT> org>
3 AuthorDate: Sun Sep 27 10:02:00 2020 +0000
4 Commit: Jeroen Roovers <jer <AT> gentoo <DOT> org>
5 CommitDate: Sun Sep 27 10:06:54 2020 +0000
6 URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=af1632be
7
8 dev-libs/libdnet: Add ndisc patch
9
10 Package-Manager: Portage-3.0.8, Repoman-3.0.1
11 Bug: https://bugs.gentoo.org/744484
12 Signed-off-by: Jeroen Roovers <jer <AT> gentoo.org>
13
14 dev-libs/libdnet/files/libdnet-1.14-ndisc.patch | 796 ++++++++++++++++++++++++
15 dev-libs/libdnet/libdnet-1.14-r1.ebuild | 78 +++
16 2 files changed, 874 insertions(+)
17
18 diff --git a/dev-libs/libdnet/files/libdnet-1.14-ndisc.patch b/dev-libs/libdnet/files/libdnet-1.14-ndisc.patch
19 new file mode 100644
20 index 00000000000..439ffb7cb92
21 --- /dev/null
22 +++ b/dev-libs/libdnet/files/libdnet-1.14-ndisc.patch
23 @@ -0,0 +1,796 @@
24 +From 1c324828f4c6c64c9340f169bc059152dba1f998 Mon Sep 17 00:00:00 2001
25 +From: Stas Grabois <finpushack@×××××.com>
26 +Date: Sat, 5 Sep 2020 13:15:32 +0300
27 +Subject: [PATCH] IPv6 support
28 +
29 +---
30 + configure | 20 ++++
31 + configure.ac | 7 ++
32 + include/dnet.h | 1 +
33 + include/dnet/Makefile.am | 2 +-
34 + include/dnet/Makefile.in | 2 +-
35 + include/dnet/ip6.h | 3 +
36 + include/dnet/ndisc.h | 35 +++++++
37 + include/dnet/route.h | 3 +
38 + src/Makefile.in | 2 +-
39 + src/intf.c | 101 +++++++++++++-------
40 + src/ip6.c | 56 +++++++++++
41 + src/ndisc-linux.c | 197 +++++++++++++++++++++++++++++++++++++++
42 + src/ndisc-none.c | 55 +++++++++++
43 + src/route-linux.c | 95 ++++++++++++++++++-
44 + 14 files changed, 541 insertions(+), 38 deletions(-)
45 + create mode 100644 include/dnet/ndisc.h
46 + create mode 100644 src/ndisc-linux.c
47 + create mode 100644 src/ndisc-none.c
48 +
49 +--- a/configure
50 ++++ b/configure
51 +@@ -22025,6 +22025,26 @@
52 +
53 + fi
54 +
55 ++if test "$ac_cv_dnet_linux_procfs" = yes ; then
56 ++ case $LIBOBJS in
57 ++ "ndisc-linux.$ac_objext" | \
58 ++ *" ndisc-linux.$ac_objext" | \
59 ++ "ndisc-linux.$ac_objext "* | \
60 ++ *" ndisc-linux.$ac_objext "* ) ;;
61 ++ *) LIBOBJS="$LIBOBJS ndisc-linux.$ac_objext" ;;
62 ++esac
63 ++
64 ++else
65 ++ case $LIBOBJS in
66 ++ "ndisc-none.$ac_objext" | \
67 ++ *" ndisc-none.$ac_objext" | \
68 ++ "ndisc-none.$ac_objext "* | \
69 ++ *" ndisc-none.$ac_objext "* ) ;;
70 ++ *) LIBOBJS="$LIBOBJS ndisc-none.$ac_objext" ;;
71 ++esac
72 ++
73 ++fi
74 ++
75 + if test "$ac_cv_header_linux_if_tun_h" = yes ; then
76 + case $LIBOBJS in
77 + "tun-linux.$ac_objext" | \
78 +--- a/configure.ac
79 ++++ b/configure.ac
80 +@@ -303,6 +303,13 @@
81 + AC_LIBOBJ([route-none])
82 + fi
83 +
84 ++dnl Check for ndisc interface.
85 ++if test "$ac_cv_dnet_linux_procfs" = yes ; then
86 ++ AC_LIBOBJ([ndisc-linux])
87 ++else
88 ++ AC_LIBOBJ([ndisc-none])
89 ++fi
90 ++
91 + dnl Check for tun interface.
92 + if test "$ac_cv_header_linux_if_tun_h" = yes ; then
93 + AC_LIBOBJ([tun-linux])
94 +--- a/include/dnet.h
95 ++++ b/include/dnet.h
96 +@@ -16,6 +16,7 @@
97 + #include <dnet/ip6.h>
98 + #include <dnet/addr.h>
99 + #include <dnet/arp.h>
100 ++#include <dnet/ndisc.h>
101 + #include <dnet/icmp.h>
102 + #include <dnet/tcp.h>
103 + #include <dnet/udp.h>
104 +--- a/include/dnet/Makefile.am
105 ++++ b/include/dnet/Makefile.am
106 +@@ -5,4 +5,4 @@
107 + dnetincludedir = $(includedir)/dnet
108 +
109 + dnetinclude_HEADERS = addr.h arp.h blob.h eth.h fw.h icmp.h intf.h ip.h \
110 +- ip6.h os.h rand.h route.h tcp.h tun.h udp.h sctp.h
111 ++ ip6.h os.h rand.h route.h tcp.h tun.h udp.h sctp.h ndisc.h
112 +--- a/include/dnet/Makefile.in
113 ++++ b/include/dnet/Makefile.in
114 +@@ -106,7 +106,7 @@
115 + dnetincludedir = $(includedir)/dnet
116 +
117 + dnetinclude_HEADERS = addr.h arp.h blob.h eth.h fw.h icmp.h intf.h ip.h \
118 +- ip6.h os.h rand.h route.h tcp.h tun.h udp.h sctp.h
119 ++ ip6.h os.h rand.h route.h tcp.h tun.h udp.h sctp.h ndisc.h
120 +
121 + subdir = include/dnet
122 + mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
123 +--- a/include/dnet/ip6.h
124 ++++ b/include/dnet/ip6.h
125 +@@ -179,6 +179,9 @@
126 + char *ip6_ntoa(const ip6_addr_t *ip6);
127 + #define ip6_aton ip6_pton
128 +
129 ++ssize_t ip6_add_option(void *buf, size_t len,
130 ++ int proto, const void *optbuf, size_t optlen);
131 ++
132 + void ip6_checksum(void *buf, size_t len);
133 + __END_DECLS
134 +
135 +new file mode 100644
136 +--- a//dev/null
137 ++++ b/include/dnet/ndisc.h
138 +@@ -0,0 +1,35 @@
139 ++/*
140 ++ * ndisc.c
141 ++ *
142 ++ * Kernel arp/ndisc table operations.
143 ++ *
144 ++ * Copyright (c) 2000 Dug Song <dugsong@××××××.org>
145 ++ *
146 ++ */
147 ++
148 ++#ifndef DNET_NDISC_H
149 ++#define DNET_NDISC_H
150 ++
151 ++/*
152 ++ * NDISC cache entry
153 ++ */
154 ++struct ndisc_entry {
155 ++ int intf_index;
156 ++ struct addr ndisc_pa; /* protocol address */
157 ++ struct addr ndisc_ha; /* hardware address */
158 ++};
159 ++
160 ++typedef struct ndisc_handle ndisc_t;
161 ++
162 ++typedef int (*ndisc_handler)(const struct ndisc_entry *entry, void *arg);
163 ++
164 ++__BEGIN_DECLS
165 ++ndisc_t *ndisc_open(void);
166 ++int ndisc_add(ndisc_t *n, const struct ndisc_entry *entry);
167 ++int ndisc_delete(ndisc_t *n, const struct ndisc_entry *entry);
168 ++int ndisc_get(ndisc_t *n, struct ndisc_entry *entry);
169 ++int ndisc_loop(ndisc_t *n, ndisc_handler callback, void *arg);
170 ++ndisc_t *ndisc_close(ndisc_t *r);
171 ++__END_DECLS
172 ++
173 ++#endif /* DNET_NDISC_H */
174 +--- a/include/dnet/route.h
175 ++++ b/include/dnet/route.h
176 +@@ -26,7 +26,10 @@
177 + __BEGIN_DECLS
178 + route_t *route_open(void);
179 + int route_add(route_t *r, const struct route_entry *entry);
180 ++int route_add_dev(route_t *r, const struct route_entry *entry, const char* dev);
181 ++int route6_add(route_t *r, const struct route_entry *entry, int intf_index);
182 + int route_delete(route_t *r, const struct route_entry *entry);
183 ++int route6_delete(route_t *r, const struct route_entry *entry, int intf_index);
184 + int route_get(route_t *r, struct route_entry *entry);
185 + int route_loop(route_t *r, route_handler callback, void *arg);
186 + route_t *route_close(route_t *r);
187 +--- a/src/Makefile.in
188 ++++ b/src/Makefile.in
189 +@@ -144,7 +144,7 @@
190 + intf-win32.c intf.c ip-cooked.c ip-win32.c ip.c memcmp.c \
191 + route-bsd.c route-hpux.c route-linux.c route-none.c \
192 + route-win32.c strlcat.c strlcpy.c strsep.c tun-bsd.c \
193 +- tun-linux.c tun-none.c tun-solaris.c
194 ++ tun-linux.c tun-none.c tun-solaris.c ndisc-linux.c ndisc-none.c
195 + SOURCES = $(libdnet_la_SOURCES)
196 +
197 + all: all-am
198 +--- a/src/intf.c
199 ++++ b/src/intf.c
200 +@@ -20,6 +20,9 @@
201 + # define IP_MULTICAST
202 + #endif
203 + #include <net/if.h>
204 ++#ifdef HAVE_NET_IF_DL_H
205 ++# include <net/if_dl.h>
206 ++#endif
207 + #ifdef HAVE_NET_IF_VAR_H
208 + # include <net/if_var.h>
209 + #endif
210 +@@ -79,6 +82,21 @@
211 + u_char ifcbuf[4192];
212 + };
213 +
214 ++/* TODO: move to .h */
215 ++union sockunion {
216 ++#ifdef HAVE_NET_IF_DL_H
217 ++ struct sockaddr_dl sdl;
218 ++#endif
219 ++ struct sockaddr_in sin;
220 ++#ifdef HAVE_SOCKADDR_IN6
221 ++ struct sockaddr_in6 sin6;
222 ++#endif
223 ++ struct sockaddr sa;
224 ++#ifdef AF_RAW
225 ++ struct sockaddr_raw sr;
226 ++#endif
227 ++};
228 ++
229 + static int
230 + intf_flags_to_iff(u_short flags, int iff)
231 + {
232 +@@ -129,14 +147,10 @@
233 +
234 + setsockopt(intf->fd, SOL_SOCKET, SO_BROADCAST,
235 + (const char *) &one, sizeof(one));
236 +-#ifdef SIOCGIFNETMASK_IN6
237 + if ((intf->fd6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
238 +-# ifdef EPROTONOSUPPORT
239 + if (errno != EPROTONOSUPPORT)
240 +-# endif
241 + return (intf_close(intf));
242 + }
243 +-#endif
244 + }
245 + return (intf);
246 + }
247 +@@ -586,34 +600,50 @@
248 + return (_intf_get_aliases(intf, entry));
249 + }
250 +
251 ++static int
252 ++get_max_bits(const struct addr *a)
253 ++{
254 ++ if (a->addr_type == ADDR_TYPE_IP) {
255 ++ return IP_ADDR_BITS;
256 ++ } else if (a->addr_type == ADDR_TYPE_IP6) {
257 ++ return IP6_ADDR_BITS;
258 ++ } else {
259 ++ return 0;
260 ++ }
261 ++}
262 ++
263 + static int
264 + _match_intf_src(const struct intf_entry *entry, void *arg)
265 + {
266 +- int matched = 0;
267 +- int cnt;
268 + struct intf_entry *save = (struct intf_entry *)arg;
269 +-
270 +- if (entry->intf_addr.addr_type == ADDR_TYPE_IP &&
271 +- entry->intf_addr.addr_ip == save->intf_addr.addr_ip) {
272 +- matched = 1;
273 +- } else {
274 +- for (cnt = 0; !matched && cnt < (int) entry->intf_alias_num; cnt++) {
275 +- if (entry->intf_alias_addrs[cnt].addr_type != ADDR_TYPE_IP)
276 +- continue;
277 +- if (entry->intf_alias_addrs[cnt].addr_ip == save->intf_addr.addr_ip)
278 +- matched = 1;
279 +- }
280 ++ int len = save->intf_len < entry->intf_len ? save->intf_len : entry->intf_len;
281 ++ int i;
282 ++
283 ++ struct addr a, saved_addr;
284 ++
285 ++ saved_addr = save->intf_addr;
286 ++ saved_addr.addr_bits = get_max_bits(&saved_addr);
287 ++
288 ++ a = entry->intf_addr;
289 ++ a.addr_bits = get_max_bits(&a);
290 ++
291 ++ if (addr_cmp(&a, &saved_addr) == 0) {
292 ++ memcpy(save, entry, len);
293 ++ return 1;
294 + }
295 +
296 +- if (matched) {
297 +- /* XXX - truncated result if entry is too small. */
298 +- if (save->intf_len < entry->intf_len)
299 +- memcpy(save, entry, save->intf_len);
300 +- else
301 +- memcpy(save, entry, entry->intf_len);
302 +- return (1);
303 ++ for (i = 0; i < (int)entry->intf_alias_num; i++) {
304 ++ a = entry->intf_alias_addrs[i];
305 ++ a.addr_bits = get_max_bits(&a);
306 ++
307 ++ if (addr_cmp(&a, &saved_addr) == 0) {
308 ++ memcpy(save, entry, len);
309 ++ save->intf_addr = entry->intf_alias_addrs[i];
310 ++ return 1;
311 ++ }
312 + }
313 +- return (0);
314 ++
315 ++ return 0;
316 + }
317 +
318 + int
319 +@@ -631,24 +661,27 @@
320 + int
321 + intf_get_dst(intf_t *intf, struct intf_entry *entry, struct addr *dst)
322 + {
323 +- struct sockaddr_in sin;
324 ++ union sockunion sun;
325 + socklen_t n;
326 +
327 +- if (dst->addr_type != ADDR_TYPE_IP) {
328 ++ int fd;
329 ++
330 ++ if (dst->addr_type != ADDR_TYPE_IP && dst->addr_type != ADDR_TYPE_IP6) {
331 + errno = EINVAL;
332 + return (-1);
333 + }
334 +- addr_ntos(dst, (struct sockaddr *)&sin);
335 +- sin.sin_port = htons(666);
336 +-
337 +- if (connect(intf->fd, (struct sockaddr *)&sin, sizeof(sin)) < 0)
338 ++ addr_ntos(dst, (struct sockaddr *)&sun);
339 ++ sun.sin.sin_port = htons(666);
340 ++
341 ++ fd = dst->addr_type == ADDR_TYPE_IP6 ? intf->fd6 : intf->fd;
342 ++ if (connect(fd, (struct sockaddr *)&sun, sizeof(sun)) < 0)
343 + return (-1);
344 +
345 +- n = sizeof(sin);
346 +- if (getsockname(intf->fd, (struct sockaddr *)&sin, &n) < 0)
347 ++ n = sizeof(sun);
348 ++ if (getsockname(fd, (struct sockaddr *)&sun, &n) < 0)
349 + return (-1);
350 +
351 +- addr_ston((struct sockaddr *)&sin, &entry->intf_addr);
352 ++ addr_ston((struct sockaddr *)&sun, &entry->intf_addr);
353 +
354 + if (intf_loop(intf, _match_intf_src, entry) != 1)
355 + return (-1);
356 +--- a/src/ip6.c
357 ++++ b/src/ip6.c
358 +@@ -9,6 +9,8 @@
359 + #include "config.h"
360 +
361 + #include "dnet.h"
362 ++#include <string.h>
363 ++#include <errno.h>
364 +
365 + #define IP6_IS_EXT(n) \
366 + ((n) == IP_PROTO_HOPOPTS || (n) == IP_PROTO_DSTOPTS || \
367 +@@ -70,3 +72,57 @@
368 + }
369 + }
370 + }
371 ++
372 ++ssize_t
373 ++ip6_add_option(void *buf, size_t len, int proto,
374 ++ const void *optbuf, size_t optlen)
375 ++{
376 ++ struct ip6_hdr *ip6;
377 ++ struct tcp_hdr *tcp = NULL;
378 ++ u_char *p;
379 ++ int hl, datalen, padlen;
380 ++
381 ++ if (proto != IP_PROTO_TCP) {
382 ++ errno = EINVAL;
383 ++ return (-1);
384 ++ }
385 ++
386 ++ ip6 = (struct ip6_hdr *)buf;
387 ++ p = (u_char *)buf + IP6_HDR_LEN;
388 ++
389 ++ tcp = (struct tcp_hdr *)p;
390 ++ hl = tcp->th_off << 2;
391 ++ p = (u_char *)tcp + hl;
392 ++
393 ++ datalen = ntohs(ip6->ip6_plen) + IP6_HDR_LEN - (p - (u_char *)buf);
394 ++
395 ++ /* Compute padding to next word boundary. */
396 ++ if ((padlen = 4 - (optlen % 4)) == 4)
397 ++ padlen = 0;
398 ++
399 ++ /* XXX - IP_HDR_LEN_MAX == TCP_HDR_LEN_MAX */
400 ++ if (hl + optlen + padlen > IP_HDR_LEN_MAX ||
401 ++ ntohs(ip6->ip6_plen) + IP6_HDR_LEN + optlen + padlen > len) {
402 ++ errno = EINVAL;
403 ++ return (-1);
404 ++ }
405 ++
406 ++ /* Shift any existing data. */
407 ++ if (datalen) {
408 ++ memmove(p + optlen + padlen, p, datalen);
409 ++ }
410 ++ /* XXX - IP_OPT_NOP == TCP_OPT_NOP */
411 ++ if (padlen) {
412 ++ memset(p, IP_OPT_NOP, padlen);
413 ++ p += padlen;
414 ++ }
415 ++ memmove(p, optbuf, optlen);
416 ++ p += optlen;
417 ++ optlen += padlen;
418 ++
419 ++ tcp->th_off = (p - (u_char *)tcp) >> 2;
420 ++
421 ++ ip6->ip6_plen = htons(ntohs(ip6->ip6_plen) + optlen);
422 ++
423 ++ return (optlen);
424 ++}
425 +new file mode 100644
426 +--- a//dev/null
427 ++++ b/src/ndisc-linux.c
428 +@@ -0,0 +1,197 @@
429 ++/*
430 ++ * ndisc-linux.c
431 ++ *
432 ++ * Copyright (c) 2000 Dug Song <dugsong@××××××.org>
433 ++ *
434 ++ */
435 ++
436 ++#include "config.h"
437 ++
438 ++#include <sys/types.h>
439 ++#include <sys/ioctl.h>
440 ++#include <sys/socket.h>
441 ++#include <sys/uio.h>
442 ++
443 ++#include <asm/types.h>
444 ++#include <netinet/in.h>
445 ++#include <linux/netlink.h>
446 ++#include <linux/rtnetlink.h>
447 ++
448 ++#include <net/route.h>
449 ++
450 ++#include <ctype.h>
451 ++#include <errno.h>
452 ++#include <stdio.h>
453 ++#include <stdlib.h>
454 ++#include <string.h>
455 ++#include <unistd.h>
456 ++
457 ++#include "dnet.h"
458 ++
459 ++struct ndisc_handle
460 ++{
461 ++ int nlfd;
462 ++ int seq;
463 ++};
464 ++
465 ++ndisc_t *
466 ++ndisc_open(void)
467 ++{
468 ++ struct sockaddr_nl snl;
469 ++ ndisc_t *n;
470 ++
471 ++ if ((n = calloc(1, sizeof(*n))) != NULL) {
472 ++ n->nlfd = -1;
473 ++
474 ++ if ((n->nlfd = socket(AF_NETLINK, SOCK_RAW,
475 ++ NETLINK_ROUTE)) < 0)
476 ++ return (ndisc_close(n));
477 ++
478 ++ memset(&snl, 0, sizeof(snl));
479 ++ snl.nl_family = AF_NETLINK;
480 ++
481 ++ if (bind(n->nlfd, (struct sockaddr *)&snl, sizeof(snl)) < 0)
482 ++ return (ndisc_close(n));
483 ++ }
484 ++ return (n);
485 ++}
486 ++
487 ++static int
488 ++netlink_addattr(struct nlmsghdr *n, int type, const void *data, int data_len)
489 ++{
490 ++ int len = RTA_LENGTH(data_len);
491 ++ struct rtattr *rta;
492 ++
493 ++ rta = (struct rtattr *)((uint8_t*)n + NLMSG_ALIGN(n->nlmsg_len));
494 ++ rta->rta_type = type;
495 ++ rta->rta_len = len;
496 ++ memcpy(RTA_DATA(rta), data, data_len);
497 ++ n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len);
498 ++ return 0;
499 ++}
500 ++
501 ++int
502 ++ndisc_modify(ndisc_t *n, const struct ndisc_entry *entry, int type, int flags)
503 ++{
504 ++ struct nlmsghdr *nmsg;
505 ++ struct ndmsg *ndm;
506 ++ struct rtattr *rta;
507 ++ struct sockaddr_nl snl;
508 ++ struct iovec iov;
509 ++ struct msghdr msg;
510 ++ u_char buf[512];
511 ++ int i, af, alen;
512 ++
513 ++ switch (entry->ndisc_pa.addr_type) {
514 ++ case ADDR_TYPE_IP:
515 ++ af = AF_INET;
516 ++ alen = IP_ADDR_LEN;
517 ++ break;
518 ++ case ADDR_TYPE_IP6:
519 ++ af = AF_INET6;
520 ++ alen = IP6_ADDR_LEN;
521 ++ break;
522 ++ default:
523 ++ errno = EINVAL;
524 ++ return (-1);
525 ++ }
526 ++ memset(buf, 0, sizeof(buf));
527 ++
528 ++ nmsg = (struct nlmsghdr *)buf;
529 ++ nmsg->nlmsg_len = NLMSG_LENGTH(sizeof(struct ndmsg));
530 ++ nmsg->nlmsg_flags = NLM_F_REQUEST | flags;
531 ++ nmsg->nlmsg_type = type;
532 ++ nmsg->nlmsg_seq = ++n->seq;
533 ++
534 ++ nmsg->nlmsg_flags |= NLM_F_ACK;
535 ++
536 ++ ndm = (struct ndmsg *)(nmsg + 1);
537 ++ ndm->ndm_family = af;
538 ++ ndm->ndm_state = NUD_PERMANENT;
539 ++ ndm->ndm_ifindex = entry->intf_index;
540 ++
541 ++ netlink_addattr(nmsg, NDA_DST, &entry->ndisc_pa.addr_data8[0],
542 ++ alen);
543 ++
544 ++ if (type == RTM_NEWNEIGH) {
545 ++ netlink_addattr(nmsg, NDA_LLADDR,
546 ++ &entry->ndisc_ha.addr_data8[0], ETH_ADDR_LEN);
547 ++ }
548 ++
549 ++ memset(&snl, 0, sizeof(snl));
550 ++ snl.nl_family = AF_NETLINK;
551 ++
552 ++ iov.iov_base = nmsg;
553 ++ iov.iov_len = nmsg->nlmsg_len;
554 ++
555 ++ memset(&msg, 0, sizeof(msg));
556 ++ msg.msg_name = &snl;
557 ++ msg.msg_namelen = sizeof(snl);
558 ++ msg.msg_iov = &iov;
559 ++ msg.msg_iovlen = 1;
560 ++
561 ++ if (sendmsg(n->nlfd, &msg, 0) < 0)
562 ++ return (-1);
563 ++
564 ++ iov.iov_base = buf;
565 ++ iov.iov_len = sizeof(buf);
566 ++
567 ++ if ((i = recvmsg(n->nlfd, &msg, 0)) <= 0)
568 ++ return (-1);
569 ++
570 ++ if (nmsg->nlmsg_len < (int)sizeof(*nmsg) || nmsg->nlmsg_len > i ||
571 ++ nmsg->nlmsg_seq != n->seq) {
572 ++ errno = EINVAL;
573 ++ return (-1);
574 ++ }
575 ++ if (nmsg->nlmsg_type == NLMSG_ERROR) {
576 ++ struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(nmsg);
577 ++ errno = -err->error;
578 ++ if (errno == 0) {
579 ++ return 0;
580 ++ }
581 ++
582 ++ return (-1);
583 ++ }
584 ++
585 ++ return (-1);
586 ++}
587 ++
588 ++int
589 ++ndisc_add(ndisc_t *n, const struct ndisc_entry *entry)
590 ++{
591 ++ return ndisc_modify(n, entry, RTM_NEWNEIGH, NLM_F_CREATE | NLM_F_EXCL);
592 ++}
593 ++
594 ++int
595 ++ndisc_delete(ndisc_t *n, const struct ndisc_entry *entry)
596 ++{
597 ++ return ndisc_modify(n, entry, RTM_DELNEIGH, 0);
598 ++}
599 ++
600 ++int
601 ++ndisc_get(ndisc_t *n, struct ndisc_entry *entry)
602 ++{
603 ++ /* TBD */
604 ++ errno = ENOSYS;
605 ++ return (-1);
606 ++}
607 ++
608 ++int
609 ++nsidc_loop(ndisc_t *n, ndisc_handler callback, void *arg)
610 ++{
611 ++ /* TBD */
612 ++ errno = ENOSYS;
613 ++ return (-1);
614 ++}
615 ++
616 ++ndisc_t *
617 ++ndisc_close(ndisc_t *n)
618 ++{
619 ++ if (n != NULL) {
620 ++ if (n->nlfd >= 0)
621 ++ close(n->nlfd);
622 ++ free(n);
623 ++ }
624 ++ return (NULL);
625 ++}
626 +new file mode 100644
627 +--- a//dev/null
628 ++++ b/src/ndisc-none.c
629 +@@ -0,0 +1,55 @@
630 ++/*
631 ++ * ndisc-linux.c
632 ++ *
633 ++ * Copyright (c) 2000 Dug Song <dugsong@××××××.org>
634 ++ *
635 ++ */
636 ++
637 ++#include "config.h"
638 ++
639 ++#include <errno.h>
640 ++#include <stdio.h>
641 ++#include <stdlib.h>
642 ++
643 ++#include "dnet.h"
644 ++
645 ++ndisc_t *
646 ++ndisc_open(void)
647 ++{
648 ++ errno = ENOSYS;
649 ++ return (NULL);
650 ++}
651 ++
652 ++int
653 ++ndisc_add(ndisc_t *n, const struct ndisc_entry *entry)
654 ++{
655 ++ errno = ENOSYS;
656 ++ return (-1);
657 ++}
658 ++
659 ++int
660 ++ndisc_delete(ndisc_t *n, const struct ndisc_entry *entry)
661 ++{
662 ++ errno = ENOSYS;
663 ++ return (-1);
664 ++}
665 ++
666 ++int
667 ++ndisc_get(ndisc_t *n, struct ndisc_entry *entry)
668 ++{
669 ++ errno = ENOSYS;
670 ++ return (-1);
671 ++}
672 ++
673 ++int
674 ++nsidc_loop(ndisc_t *n, ndisc_handler callback, void *arg)
675 ++{
676 ++ errno = ENOSYS;
677 ++ return (-1);
678 ++}
679 ++
680 ++ndisc_t *
681 ++ndisc_close(ndisc_t *n)
682 ++{
683 ++ return (NULL);
684 ++}
685 +--- a/src/route-linux.c
686 ++++ b/src/route-linux.c
687 +@@ -39,6 +39,7 @@
688 +
689 + struct route_handle {
690 + int fd;
691 ++ int fd6;
692 + int nlfd;
693 + };
694 +
695 +@@ -49,10 +50,13 @@
696 + route_t *r;
697 +
698 + if ((r = calloc(1, sizeof(*r))) != NULL) {
699 +- r->fd = r->nlfd = -1;
700 ++ r->fd = r->fd6 = r->nlfd = -1;
701 +
702 + if ((r->fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
703 + return (route_close(r));
704 ++
705 ++ if ((r->fd6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
706 ++ return (route_close(r));
707 +
708 + if ((r->nlfd = socket(AF_NETLINK, SOCK_RAW,
709 + NETLINK_ROUTE)) < 0)
710 +@@ -90,6 +94,67 @@
711 + return (ioctl(r->fd, SIOCADDRT, &rt));
712 + }
713 +
714 ++int
715 ++route_add_dev(route_t *r, const struct route_entry *entry, const char* dev)
716 ++{
717 ++ struct rtentry rt;
718 ++ struct addr dst;
719 ++
720 ++ memset(&rt, 0, sizeof(rt));
721 ++ rt.rt_flags = RTF_UP;
722 ++ rt.rt_dev = (char*)dev;
723 ++
724 ++ if (ADDR_ISHOST(&entry->route_dst)) {
725 ++ rt.rt_flags |= RTF_HOST;
726 ++ memcpy(&dst, &entry->route_dst, sizeof(dst));
727 ++ } else
728 ++ addr_net(&entry->route_dst, &dst);
729 ++
730 ++ if (entry->route_gw.addr_ip != 0) {
731 ++ rt.rt_flags |= RTF_GATEWAY;
732 ++ }
733 ++
734 ++ if (addr_ntos(&dst, &rt.rt_dst) < 0 ||
735 ++ addr_ntos(&entry->route_gw, &rt.rt_gateway) < 0 ||
736 ++ addr_btos(entry->route_dst.addr_bits, &rt.rt_genmask) < 0)
737 ++ return (-1);
738 ++
739 ++ int ret = (ioctl(r->fd, SIOCADDRT, &rt));
740 ++ return ret;
741 ++}
742 ++
743 ++int
744 ++route6_add(route_t *r, const struct route_entry *entry, int intf_index)
745 ++{
746 ++ struct in6_rtmsg rt;
747 ++ struct addr dst;
748 ++
749 ++ memset(&rt, 0, sizeof(rt));
750 ++ rt.rtmsg_flags = RTF_UP;
751 ++
752 ++ if (ADDR_ISHOST(&entry->route_dst)) {
753 ++ rt.rtmsg_flags |= RTF_HOST;
754 ++ memcpy(&dst, &entry->route_dst, sizeof(dst));
755 ++ } else {
756 ++ addr_net(&entry->route_dst, &dst);
757 ++ }
758 ++
759 ++ rt.rtmsg_dst_len = entry->route_dst.addr_bits;
760 ++ rt.rtmsg_ifindex = intf_index;
761 ++ rt.rtmsg_metric = 1;
762 ++
763 ++ memcpy(&rt.rtmsg_dst, &dst.addr_ip6, sizeof(rt.rtmsg_dst));
764 ++
765 ++ if (!IN6_IS_ADDR_UNSPECIFIED(&entry->route_gw.addr_ip6)) {
766 ++ rt.rtmsg_flags |= RTF_GATEWAY;
767 ++ memcpy(&rt.rtmsg_gateway, &entry->route_gw.addr_ip6,
768 ++ sizeof(rt.rtmsg_gateway));
769 ++ }
770 ++
771 ++ int ret = (ioctl(r->fd6, SIOCADDRT, &rt));
772 ++ return ret;
773 ++}
774 ++
775 + int
776 + route_delete(route_t *r, const struct route_entry *entry)
777 + {
778 +@@ -112,6 +177,32 @@
779 + return (ioctl(r->fd, SIOCDELRT, &rt));
780 + }
781 +
782 ++int
783 ++route6_delete(route_t *r, const struct route_entry *entry, int intf_index)
784 ++{
785 ++ struct in6_rtmsg rt;
786 ++ struct addr dst;
787 ++
788 ++ memset(&rt, 0, sizeof(rt));
789 ++ rt.rtmsg_flags = RTF_UP;
790 ++
791 ++ if (ADDR_ISHOST(&entry->route_dst)) {
792 ++ rt.rtmsg_flags |= RTF_HOST;
793 ++ memcpy(&dst, &entry->route_dst, sizeof(dst));
794 ++ } else
795 ++ addr_net(&entry->route_dst, &dst);
796 ++
797 ++ rt.rtmsg_dst_len = entry->route_dst.addr_bits;
798 ++ rt.rtmsg_ifindex = intf_index;
799 ++ rt.rtmsg_metric = 1;
800 ++
801 ++ memcpy(&rt.rtmsg_dst, &dst, sizeof(rt.rtmsg_dst));
802 ++ memcpy(&rt.rtmsg_gateway, &entry->route_gw, sizeof(rt.rtmsg_gateway));
803 ++
804 ++ int ret = (ioctl(r->fd6, SIOCDELRT, &rt));
805 ++ return ret;
806 ++}
807 ++
808 + int
809 + route_get(route_t *r, struct route_entry *entry)
810 + {
811 +@@ -278,6 +369,8 @@
812 + if (r != NULL) {
813 + if (r->fd >= 0)
814 + close(r->fd);
815 ++ if (r->fd6 >= 0)
816 ++ close(r->fd6);
817 + if (r->nlfd >= 0)
818 + close(r->nlfd);
819 + free(r);
820
821 diff --git a/dev-libs/libdnet/libdnet-1.14-r1.ebuild b/dev-libs/libdnet/libdnet-1.14-r1.ebuild
822 new file mode 100644
823 index 00000000000..a709c3f636c
824 --- /dev/null
825 +++ b/dev-libs/libdnet/libdnet-1.14-r1.ebuild
826 @@ -0,0 +1,78 @@
827 +# Copyright 1999-2020 Gentoo Authors
828 +# Distributed under the terms of the GNU General Public License v2
829 +
830 +EAPI=7
831 +AT_M4DIR="config"
832 +PYTHON_COMPAT=( python3_{6,7,8} )
833 +DISTUTILS_OPTIONAL=1
834 +inherit autotools distutils-r1
835 +
836 +DESCRIPTION="simplified, portable interface to several low-level networking routines"
837 +HOMEPAGE="https://github.com/ofalk/libdnet"
838 +SRC_URI="https://github.com/ofalk/${PN}/archive/${P}.tar.gz"
839 +LICENSE="LGPL-2"
840 +
841 +SLOT="0"
842 +KEYWORDS="~alpha ~amd64 ~arm ~hppa ~ia64 ~mips ~ppc ~ppc64 ~sparc ~x86"
843 +IUSE="python static-libs test"
844 +
845 +DEPEND="
846 + python? ( ${PYTHON_DEPS} )
847 +"
848 +RDEPEND="
849 + ${DEPEND}
850 +"
851 +RESTRICT="test"
852 +REQUIRED_USE="python? ( ${PYTHON_REQUIRED_USE} )"
853 +DOCS=( README.md THANKS TODO )
854 +S=${WORKDIR}/${PN}-${P}
855 +PATCHES=(
856 + "${FILESDIR}"/${PN}-1.14-ndisc.patch
857 + "${FILESDIR}"/${PN}-1.14-strlcpy.patch
858 +)
859 +
860 +src_prepare() {
861 + default
862 +
863 + sed -i \
864 + -e 's/libcheck.a/libcheck.so/g' \
865 + -e 's|AM_CONFIG_HEADER|AC_CONFIG_HEADERS|g' \
866 + configure.ac || die
867 + sed -i \
868 + -e 's|-L$libdir ||g' \
869 + dnet-config.in || die
870 + sed -i \
871 + -e '/^SUBDIRS/s|python||g' \
872 + Makefile.am || die
873 +
874 + eautoreconf
875 +
876 + if use python; then
877 + cd python
878 + distutils-r1_src_prepare
879 + fi
880 +}
881 +
882 +src_configure() {
883 + econf \
884 + $(use_with python) \
885 + $(use_enable static-libs static)
886 +}
887 +
888 +src_compile() {
889 + default
890 + if use python; then
891 + cd python
892 + distutils-r1_src_compile
893 + fi
894 +}
895 +
896 +src_install() {
897 + default
898 + if use python; then
899 + cd python
900 + unset DOCS
901 + distutils-r1_src_install
902 + fi
903 + find "${D}" -name '*.la' -delete || die
904 +}