blob: e4847c6f40f6742292e798e3020c45f33654fc34 [file] [log] [blame]
Samuel Tand7ed8512015-08-13 16:11:35 -07001/*
2 * dhcpcd - DHCP client daemon
3 * Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
4 * All rights reserved
5
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <asm/types.h> /* Needed for 2.4 kernels */
29
30#include <sys/types.h>
31#include <sys/socket.h>
32#include <sys/ioctl.h>
33#include <sys/param.h>
34
35#include <linux/if_addr.h>
36#include <linux/if_link.h>
37#include <linux/if_packet.h>
38#include <linux/filter.h>
39#include <linux/netlink.h>
40#include <linux/rtnetlink.h>
41
42#include <arpa/inet.h>
43#include <net/if.h>
44#include <netinet/if_ether.h>
45#include <netinet/in_systm.h>
46#include <netinet/in.h>
47#include <net/route.h>
48
49/* Support older kernels */
50#ifndef IFLA_WIRELESS
51# define IFLA_WIRELESS (IFLA_MASTER + 1)
52#endif
53
54/* Linux has these in an enum and there is just no way to work
55 * out of they exist at compile time. Silly silly silly. */
56#define IFLA_AF_SPEC 26
57#define IFLA_INET6_ADDR_GEN_MODE 8
58#define IN6_ADDR_GEN_MODE_NONE 1
59
60/* For some reason, glibc doesn't include newer flags from linux/if.h
61 * However, we cannot include linux/if.h directly as it conflicts
62 * with the glibc version. D'oh! */
63#ifndef IFF_LOWER_UP
64#define IFF_LOWER_UP 0x10000 /* driver signals L1 up */
65#endif
66
67#include <errno.h>
68#include <fcntl.h>
69#include <ctype.h>
70#include <stddef.h>
71#include <stdio.h>
72#include <stdlib.h>
73#include <string.h>
74#include <time.h>
75#include <unistd.h>
76
77#include "config.h"
78#include "common.h"
79#include "dev.h"
80#include "dhcp.h"
81#include "if.h"
82#include "ipv4.h"
83#include "ipv6.h"
84#include "ipv6nd.h"
85
86#ifdef HAVE_NL80211_H
87#include <linux/genetlink.h>
88#include <linux/nl80211.h>
89#endif
90int if_getssid_wext(const char *ifname, uint8_t *ssid);
91
92#define bpf_insn sock_filter
93#define BPF_SKIPTYPE
94#define BPF_ETHCOOK -ETH_HLEN
95#define BPF_WHOLEPACKET 0x0fffffff /* work around buggy LPF filters */
96
97#include "bpf-filter.h"
98
99/* Broadcast address for IPoIB */
100static const uint8_t ipv4_bcast_addr[] = {
101 0x00, 0xff, 0xff, 0xff,
102 0xff, 0x12, 0x40, 0x1b, 0x00, 0x00, 0x00, 0x00,
103 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff
104};
105
106#define PROC_INET6 "/proc/net/if_inet6"
107#define PROC_PROMOTE "/proc/sys/net/ipv4/conf/%s/promote_secondaries"
108#define SYS_LAYER2 "/sys/class/net/%s/device/layer2"
109
110static const char *mproc =
111#if defined(__alpha__)
112 "system type"
113#elif defined(__arm__)
114 "Hardware"
115#elif defined(__avr32__)
116 "cpu family"
117#elif defined(__bfin__)
118 "BOARD Name"
119#elif defined(__cris__)
120 "cpu model"
121#elif defined(__frv__)
122 "System"
123#elif defined(__i386__) || defined(__x86_64__)
124 "vendor_id"
125#elif defined(__ia64__)
126 "vendor"
127#elif defined(__hppa__)
128 "model"
129#elif defined(__m68k__)
130 "MMU"
131#elif defined(__mips__)
132 "system type"
133#elif defined(__powerpc__) || defined(__powerpc64__)
134 "machine"
135#elif defined(__s390__) || defined(__s390x__)
136 "Manufacturer"
137#elif defined(__sh__)
138 "machine"
139#elif defined(sparc) || defined(__sparc__)
140 "cpu"
141#elif defined(__vax__)
142 "cpu"
143#else
144 NULL
145#endif
146 ;
147
148int
149if_machinearch(char *str, size_t len)
150{
151 FILE *fp;
152 char buf[256];
153
154 if (mproc == NULL) {
155 errno = EINVAL;
156 return -1;
157 }
158
159 fp = fopen("/proc/cpuinfo", "r");
160 if (fp == NULL)
161 return -1;
162
163 while (fscanf(fp, "%255s : ", buf) != EOF) {
164 if (strncmp(buf, mproc, strlen(mproc)) == 0 &&
165 fscanf(fp, "%255s", buf) == 1)
166 {
167 fclose(fp);
168 return snprintf(str, len, ":%s", buf);
169 }
170 }
171 fclose(fp);
172 errno = ESRCH;
173 return -1;
174}
175
176static int
177check_proc_int(const char *path)
178{
179 FILE *fp;
180 int i;
181
182 fp = fopen(path, "r");
183 if (fp == NULL)
184 return -1;
185 if (fscanf(fp, "%d", &i) != 1)
186 i = -1;
187 fclose(fp);
188 return i;
189}
190
191static ssize_t
192write_path(const char *path, const char *val)
193{
194 FILE *fp;
195 ssize_t r;
196
197 fp = fopen(path, "w");
198 if (fp == NULL)
199 return -1;
200 r = fprintf(fp, "%s\n", val);
201 fclose(fp);
202 return r;
203}
204
205int
206if_init(struct interface *ifp)
207{
208 char path[sizeof(PROC_PROMOTE) + IF_NAMESIZE];
209 int n;
210
211 /* We enable promote_secondaries so that we can do this
212 * add 192.168.1.2/24
213 * add 192.168.1.3/24
214 * del 192.168.1.2/24
215 * and the subnet mask moves onto 192.168.1.3/24
216 * This matches the behaviour of BSD which makes coding dhcpcd
217 * a little easier as there's just one behaviour. */
218 snprintf(path, sizeof(path), PROC_PROMOTE, ifp->name);
219 n = check_proc_int(path);
220 if (n == -1)
221 return errno == ENOENT ? 0 : -1;
222 if (n == 1)
223 return 0;
224 return write_path(path, "1") == -1 ? -1 : 0;
225}
226
227int
228if_conf(struct interface *ifp)
229{
230 char path[sizeof(SYS_LAYER2) + IF_NAMESIZE];
231 int n;
232
233 /* Some qeth setups require the use of the broadcast flag. */
234 snprintf(path, sizeof(path), SYS_LAYER2, ifp->name);
235 n = check_proc_int(path);
236 if (n == -1)
237 return errno == ENOENT ? 0 : -1;
238 if (n == 0)
239 ifp->options->options |= DHCPCD_BROADCAST;
240 return 0;
241}
242
243/* XXX work out Virtal Interface Masters */
244int
245if_vimaster(__unused const char *ifname)
246{
247
248 return 0;
249}
250
251static int
252_open_link_socket(struct sockaddr_nl *nl, int flags, int protocol)
253{
254 int fd;
255
256#ifdef SOCK_CLOEXEC
257 if (flags)
258 flags = SOCK_CLOEXEC;
259 fd = socket(AF_NETLINK, SOCK_RAW | flags, protocol);
260 if (fd == -1)
261 return -1;
262#else
263 fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
264 if (fd == -1)
265 return -1;
266 if (flags &&
267 (flags = fcntl(fd, F_GETFD, 0)) == -1 ||
268 fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1)
269 {
270 close(fd);
271 return -1;
272 }
273#endif
274 nl->nl_family = AF_NETLINK;
275 if (bind(fd, (struct sockaddr *)nl, sizeof(*nl)) == -1) {
276 close(fd);
277 return -1;
278 }
279 return fd;
280}
281
282int
283if_openlinksocket(void)
284{
285 struct sockaddr_nl snl;
286
287 memset(&snl, 0, sizeof(snl));
288 snl.nl_groups = RTMGRP_LINK;
289
290#ifdef INET
291 snl.nl_groups |= RTMGRP_IPV4_ROUTE | RTMGRP_IPV4_IFADDR;
292#endif
293#ifdef INET6
294 snl.nl_groups |= RTMGRP_IPV6_ROUTE | RTMGRP_IPV6_IFADDR | RTMGRP_NEIGH;
295#endif
296
297 return _open_link_socket(&snl, 1, NETLINK_ROUTE);
298}
299
300static int
301err_netlink(struct nlmsghdr *nlm)
302{
303 struct nlmsgerr *err;
304 size_t len;
305
306 if (nlm->nlmsg_type != NLMSG_ERROR)
307 return 0;
308 len = nlm->nlmsg_len - sizeof(*nlm);
309 if (len < sizeof(*err)) {
310 errno = EBADMSG;
311 return -1;
312 }
313 err = (struct nlmsgerr *)NLMSG_DATA(nlm);
314 if (err->error == 0)
315 return (int)len;
316 errno = -err->error;
317 return -1;
318}
319
320static int
321get_netlink(struct dhcpcd_ctx *ctx, struct interface *ifp, int fd, int flags,
322 int (*callback)(struct dhcpcd_ctx *, struct interface *, struct nlmsghdr *))
323{
324 char *buf = NULL, *nbuf;
325 ssize_t bytes;
326 size_t buflen;
327 struct nlmsghdr *nlm;
328 struct sockaddr_nl nladdr;
329 socklen_t nladdr_len;
330 int r;
331
332 buflen = 0;
333 r = -1;
334 for (;;) {
335 bytes = recv(fd, NULL, 0,
336 flags | MSG_PEEK | MSG_DONTWAIT | MSG_TRUNC);
337 if (bytes == -1)
338 goto eexit;
339 if ((size_t)bytes == buflen) {
340 /* Support kernels older than 2.6.22 */
341 if (bytes == 0)
342 bytes = 512;
343 else
344 bytes *= 2;
345 }
346 if (buflen < (size_t)bytes) {
347 /* Alloc 1 more so we work with older kernels */
348 buflen = (size_t)bytes + 1;
349 nbuf = realloc(buf, buflen);
350 if (nbuf == NULL)
351 goto eexit;
352 buf = nbuf;
353 }
354 nladdr_len = sizeof(nladdr);
355 bytes = recvfrom(fd, buf, buflen, flags,
356 (struct sockaddr *)&nladdr, &nladdr_len);
357 if (bytes == -1 || bytes == 0)
358 goto eexit;
359
360 /* Check sender */
361 if (nladdr_len != sizeof(nladdr)) {
362 errno = EINVAL;
363 goto eexit;
364 }
365 /* Ignore message if it is not from kernel */
366 if (nladdr.nl_pid != 0) {
367 r = 0;
368 continue;
369 }
370
371 for (nlm = (struct nlmsghdr *)(void *)buf;
372 nlm && NLMSG_OK(nlm, (size_t)bytes);
373 nlm = NLMSG_NEXT(nlm, bytes))
374 {
375 r = err_netlink(nlm);
376 if (r == -1)
377 goto eexit;
378 if (r)
379 continue;
380 if (callback) {
381 r = callback(ctx, ifp, nlm);
382 if (r != 0)
383 goto eexit;
384 }
385 }
386 }
387
388eexit:
389 free(buf);
390 return r;
391}
392
393#ifdef INET
394static int
395if_copyrt(struct dhcpcd_ctx *ctx, struct rt *rt, struct nlmsghdr *nlm)
396{
397 size_t len;
398 struct rtmsg *rtm;
399 struct rtattr *rta;
400 struct in_addr prefsrc;
401
402 len = nlm->nlmsg_len - sizeof(*nlm);
403 if (len < sizeof(*rtm)) {
404 errno = EBADMSG;
405 return -1;
406 }
407 rtm = (struct rtmsg *)NLMSG_DATA(nlm);
408 if (rtm->rtm_table != RT_TABLE_MAIN || rtm->rtm_family != AF_INET)
409 return -1;
410
411 memset(rt, 0, sizeof(*rt));
412 if (rtm->rtm_type == RTN_UNREACHABLE)
413 rt->flags = RTF_REJECT;
414 if (rtm->rtm_scope == RT_SCOPE_HOST)
415 rt->flags |= RTF_HOST;
416
417 prefsrc.s_addr = INADDR_ANY;
418 rta = (struct rtattr *)RTM_RTA(rtm);
419 len = RTM_PAYLOAD(nlm);
420 while (RTA_OK(rta, len)) {
421 switch (rta->rta_type) {
422 case RTA_DST:
423 memcpy(&rt->dest.s_addr, RTA_DATA(rta),
424 sizeof(rt->dest.s_addr));
425 break;
426 case RTA_GATEWAY:
427 memcpy(&rt->gate.s_addr, RTA_DATA(rta),
428 sizeof(rt->gate.s_addr));
429 break;
430 case RTA_PREFSRC:
431 memcpy(&prefsrc.s_addr, RTA_DATA(rta),
432 sizeof(prefsrc.s_addr));
433 break;
434 case RTA_OIF:
435 rt->iface = if_findindex(ctx->ifaces,
436 *(unsigned int *)RTA_DATA(rta));
437 break;
438 case RTA_PRIORITY:
439 rt->metric = *(unsigned int *)RTA_DATA(rta);
440 break;
441 }
442 rta = RTA_NEXT(rta, len);
443 }
444
445 inet_cidrtoaddr(rtm->rtm_dst_len, &rt->net);
446 if (rt->iface == NULL && prefsrc.s_addr != INADDR_ANY) {
447 struct ipv4_addr *ap;
448
449 /* For some reason the default route comes back with the
450 * loopback interface in RTA_OIF? Lets find it by
451 * preferred source address */
452 if ((ap = ipv4_findaddr(ctx, &prefsrc)))
453 rt->iface = ap->iface;
454 }
455 return 0;
456}
457#endif
458
459#ifdef INET6
460static int
461if_copyrt6(struct dhcpcd_ctx *ctx, struct rt6 *rt, struct nlmsghdr *nlm)
462{
463 size_t len;
464 struct rtmsg *rtm;
465 struct rtattr *rta;
466
467 len = nlm->nlmsg_len - sizeof(*nlm);
468 if (len < sizeof(*rtm)) {
469 errno = EBADMSG;
470 return -1;
471 }
472 rtm = (struct rtmsg *)NLMSG_DATA(nlm);
473 if (rtm->rtm_table != RT_TABLE_MAIN || rtm->rtm_family != AF_INET6)
474 return -1;
475
476 memset(rt, 0, sizeof(*rt));
477 if (rtm->rtm_type == RTN_UNREACHABLE)
478 rt->flags = RTF_REJECT;
479 if (rtm->rtm_scope == RT_SCOPE_HOST)
480 rt->flags |= RTF_HOST;
481 ipv6_mask(&rt->net, rtm->rtm_dst_len);
482
483 rta = (struct rtattr *)RTM_RTA(rtm);
484 len = RTM_PAYLOAD(nlm);
485 while (RTA_OK(rta, len)) {
486 switch (rta->rta_type) {
487 case RTA_DST:
488 memcpy(&rt->dest.s6_addr, RTA_DATA(rta),
489 sizeof(rt->dest.s6_addr));
490 break;
491 case RTA_GATEWAY:
492 memcpy(&rt->gate.s6_addr, RTA_DATA(rta),
493 sizeof(rt->gate.s6_addr));
494 break;
495 case RTA_OIF:
496 rt->iface = if_findindex(ctx->ifaces,
497 *(unsigned int *)RTA_DATA(rta));
498 break;
499 case RTA_PRIORITY:
500 rt->metric = *(unsigned int *)RTA_DATA(rta);
501 break;
502 }
503 rta = RTA_NEXT(rta, len);
504 }
505
506 return 0;
507}
508#endif
509
510/* Work out the maximum pid size */
511static inline long long
512get_max_pid_t()
513{
514
515 if (sizeof(pid_t) == sizeof(short)) return SHRT_MAX;
516 if (sizeof(pid_t) == sizeof(int)) return INT_MAX;
517 if (sizeof(pid_t) == sizeof(long)) return LONG_MAX;
518 if (sizeof(pid_t) == sizeof(long long)) return LLONG_MAX;
519 abort();
520}
521
522static int
523link_route(struct dhcpcd_ctx *ctx, __unused struct interface *ifp,
524 struct nlmsghdr *nlm)
525{
526 size_t len;
527 struct rtmsg *rtm;
528 int cmd;
529#ifdef INET
530 struct rt rt;
531#endif
532#ifdef INET6
533 struct rt6 rt6;
534#endif
535 switch (nlm->nlmsg_type) {
536 case RTM_NEWROUTE:
537 cmd = RTM_ADD;
538 break;
539 case RTM_DELROUTE:
540 cmd = RTM_DELETE;
541 break;
542 default:
543 return 0;
544 }
545
546 len = nlm->nlmsg_len - sizeof(*nlm);
547 if (len < sizeof(*rtm)) {
548 errno = EBADMSG;
549 return -1;
550 }
551
552 /* Ignore messages generated by us.
553 * For some reason we get messages generated by us
554 * with a very large value in nlmsg_pid that seems to be
555 * sequentially changing. Is there a better test for this? */
556 if (nlm->nlmsg_pid > get_max_pid_t())
557 return 1;
558
559 rtm = NLMSG_DATA(nlm);
560 switch (rtm->rtm_family) {
561#ifdef INET
562 case AF_INET:
563 if (if_copyrt(ctx, &rt, nlm) == 0)
564 ipv4_handlert(ctx, cmd, &rt);
565 break;
566#endif
567#ifdef INET6
568 case AF_INET6:
569 if (if_copyrt6(ctx, &rt6, nlm) == 0)
570 ipv6_handlert(ctx, cmd, &rt6);
571 break;
572#endif
573 }
574
575 return 0;
576}
577
578static int
579link_addr(struct dhcpcd_ctx *ctx, struct interface *ifp, struct nlmsghdr *nlm)
580{
581 size_t len;
582 struct rtattr *rta;
583 struct ifaddrmsg *ifa;
584#ifdef INET
585 struct in_addr addr, net, dest;
586#endif
587#ifdef INET6
588 struct in6_addr addr6;
589#endif
590
591 if (nlm->nlmsg_type != RTM_DELADDR && nlm->nlmsg_type != RTM_NEWADDR)
592 return 0;
593
594 len = nlm->nlmsg_len - sizeof(*nlm);
595 if (len < sizeof(*ifa)) {
596 errno = EBADMSG;
597 return -1;
598 }
599 ifa = NLMSG_DATA(nlm);
600 if ((ifp = if_findindex(ctx->ifaces, ifa->ifa_index)) == NULL) {
601 /* We don't know about the interface the address is for
602 * so it's not really an error */
603 return 1;
604 }
605 rta = (struct rtattr *)IFA_RTA(ifa);
606 len = NLMSG_PAYLOAD(nlm, sizeof(*ifa));
607 switch (ifa->ifa_family) {
608#ifdef INET
609 case AF_INET:
610 addr.s_addr = dest.s_addr = INADDR_ANY;
611 dest.s_addr = INADDR_ANY;
612 inet_cidrtoaddr(ifa->ifa_prefixlen, &net);
613 while (RTA_OK(rta, len)) {
614 switch (rta->rta_type) {
615 case IFA_ADDRESS:
616 if (ifp->flags & IFF_POINTOPOINT) {
617 memcpy(&dest.s_addr, RTA_DATA(rta),
618 sizeof(addr.s_addr));
619 }
620 break;
621 case IFA_LOCAL:
622 memcpy(&addr.s_addr, RTA_DATA(rta),
623 sizeof(addr.s_addr));
624 break;
625 }
626 rta = RTA_NEXT(rta, len);
627 }
628 ipv4_handleifa(ctx, nlm->nlmsg_type, NULL, ifp->name,
629 &addr, &net, &dest, ifa->ifa_flags);
630 break;
631#endif
632#ifdef INET6
633 case AF_INET6:
634 memset(&addr6, 0, sizeof(addr6));
635 while (RTA_OK(rta, len)) {
636 switch (rta->rta_type) {
637 case IFA_ADDRESS:
638 memcpy(&addr6.s6_addr, RTA_DATA(rta),
639 sizeof(addr6.s6_addr));
640 break;
641 }
642 rta = RTA_NEXT(rta, len);
643 }
644 ipv6_handleifa(ctx, nlm->nlmsg_type, NULL, ifp->name,
645 &addr6, ifa->ifa_prefixlen, ifa->ifa_flags);
646 break;
647#endif
648 }
649 return 0;
650}
651
652static uint8_t
653l2addr_len(unsigned short if_type)
654{
655
656 switch (if_type) {
657 case ARPHRD_ETHER: /* FALLTHROUGH */
658 case ARPHRD_IEEE802: /*FALLTHROUGH */
659 case ARPHRD_IEEE80211:
660 return 6;
661 case ARPHRD_IEEE1394:
662 return 8;
663 case ARPHRD_INFINIBAND:
664 return 20;
665 }
666
667 /* Impossible */
668 return 0;
669}
670
671static int
672handle_rename(struct dhcpcd_ctx *ctx, unsigned int ifindex, const char *ifname)
673{
674 struct interface *ifp;
675
676 TAILQ_FOREACH(ifp, ctx->ifaces, next) {
677 if (ifp->index == ifindex && strcmp(ifp->name, ifname)) {
678 dhcpcd_handleinterface(ctx, -1, ifp->name);
679 /* Let dev announce the interface for renaming */
680 if (!dev_listening(ctx))
681 dhcpcd_handleinterface(ctx, 1, ifname);
682 return 1;
683 }
684 }
685 return 0;
686}
687
688#ifdef INET6
689static int
690link_neigh(struct dhcpcd_ctx *ctx, __unused struct interface *ifp,
691 struct nlmsghdr *nlm)
692{
693 struct ndmsg *r;
694 struct rtattr *rta;
695 size_t len;
696 struct in6_addr addr6;
697 int flags;
698
699 if (nlm->nlmsg_type != RTM_NEWNEIGH && nlm->nlmsg_type != RTM_DELNEIGH)
700 return 0;
701 if (nlm->nlmsg_len < sizeof(*r))
702 return -1;
703
704 r = NLMSG_DATA(nlm);
705 rta = (struct rtattr *)RTM_RTA(r);
706 len = RTM_PAYLOAD(nlm);
707 if (r->ndm_family == AF_INET6) {
708 flags = 0;
709 if (r->ndm_flags & NTF_ROUTER)
710 flags |= IPV6ND_ROUTER;
711 if (nlm->nlmsg_type == RTM_NEWNEIGH &&
712 r->ndm_state &
713 (NUD_REACHABLE | NUD_STALE | NUD_DELAY | NUD_PROBE |
714 NUD_PERMANENT))
715 flags |= IPV6ND_REACHABLE;
716 memset(&addr6, 0, sizeof(addr6));
717 while (RTA_OK(rta, len)) {
718 switch (rta->rta_type) {
719 case NDA_DST:
720 memcpy(&addr6.s6_addr, RTA_DATA(rta),
721 sizeof(addr6.s6_addr));
722 break;
723 }
724 rta = RTA_NEXT(rta, len);
725 }
726 ipv6nd_neighbour(ctx, &addr6, flags);
727 }
728
729 return 0;
730}
731#endif
732
733static int
734link_netlink(struct dhcpcd_ctx *ctx, struct interface *ifp,
735 struct nlmsghdr *nlm)
736{
737 int r;
738 size_t len;
739 struct rtattr *rta, *hwaddr;
740 struct ifinfomsg *ifi;
741 char ifn[IF_NAMESIZE + 1];
742
743 r = link_route(ctx, ifp, nlm);
744 if (r != 0)
745 return r;
746 r = link_addr(ctx, ifp, nlm);
747 if (r != 0)
748 return r;
749#ifdef INET6
750 r = link_neigh(ctx, ifp, nlm);
751 if (r != 0)
752 return r;
753#endif
754
755 if (nlm->nlmsg_type != RTM_NEWLINK && nlm->nlmsg_type != RTM_DELLINK)
756 return 0;
757 len = nlm->nlmsg_len - sizeof(*nlm);
758 if ((size_t)len < sizeof(*ifi)) {
759 errno = EBADMSG;
760 return -1;
761 }
762 ifi = NLMSG_DATA(nlm);
763 if (ifi->ifi_flags & IFF_LOOPBACK)
764 return 0;
765 rta = (struct rtattr *)(void *)((char *)ifi +NLMSG_ALIGN(sizeof(*ifi)));
766 len = NLMSG_PAYLOAD(nlm, sizeof(*ifi));
767 *ifn = '\0';
768 hwaddr = NULL;
769
770 while (RTA_OK(rta, len)) {
771 switch (rta->rta_type) {
772 case IFLA_WIRELESS:
773 /* Ignore wireless messages */
774 if (nlm->nlmsg_type == RTM_NEWLINK &&
775 ifi->ifi_change == 0)
776 return 0;
777 break;
778 case IFLA_IFNAME:
779 strlcpy(ifn, RTA_DATA(rta), sizeof(ifn));
780 break;
781 case IFLA_ADDRESS:
782 hwaddr = rta;
783 break;
784 }
785 rta = RTA_NEXT(rta, len);
786 }
787
788 if (nlm->nlmsg_type == RTM_DELLINK) {
789 dhcpcd_handleinterface(ctx, -1, ifn);
790 return 0;
791 }
792
793 /* Virtual interfaces may not get a valid hardware address
794 * at this point.
795 * To trigger a valid hardware address pickup we need to pretend
796 * that that don't exist until they have one. */
797 if (ifi->ifi_flags & IFF_MASTER && !hwaddr) {
798 dhcpcd_handleinterface(ctx, -1, ifn);
799 return 0;
800 }
801
802 /* Check for interface name change */
803 if (handle_rename(ctx, (unsigned int)ifi->ifi_index, ifn))
804 return 0;
805
806 /* Check for a new interface */
807 if ((ifp = if_find(ctx->ifaces, ifn)) == NULL) {
808 /* If are listening to a dev manager, let that announce
809 * the interface rather than the kernel. */
810 if (dev_listening(ctx) < 1)
811 dhcpcd_handleinterface(ctx, 1, ifn);
812 return 0;
813 }
814
815 /* Re-read hardware address and friends */
816 if (!(ifi->ifi_flags & IFF_UP) && hwaddr) {
817 uint8_t l;
818
819 l = l2addr_len(ifi->ifi_type);
820 if (hwaddr->rta_len == RTA_LENGTH(l))
821 dhcpcd_handlehwaddr(ctx, ifn, RTA_DATA(hwaddr), l);
822 }
823
824 dhcpcd_handlecarrier(ctx,
825 ifi->ifi_flags & IFF_RUNNING ? LINK_UP : LINK_DOWN,
826 ifi->ifi_flags, ifn);
827 return 0;
828}
829
830int
831if_managelink(struct dhcpcd_ctx *ctx)
832{
833
834 return get_netlink(ctx, NULL,
835 ctx->link_fd, MSG_DONTWAIT, &link_netlink);
836}
837
838static int
839send_netlink(struct dhcpcd_ctx *ctx, struct interface *ifp,
840 int protocol, struct nlmsghdr *hdr,
841 int (*callback)(struct dhcpcd_ctx *, struct interface *, struct nlmsghdr *))
842{
843 int s, r;
844 struct sockaddr_nl snl;
845 struct iovec iov;
846 struct msghdr msg;
847 static unsigned int seq;
848
849 memset(&snl, 0, sizeof(snl));
850 if ((s = _open_link_socket(&snl, 0, protocol)) == -1)
851 return -1;
852 memset(&iov, 0, sizeof(iov));
853 iov.iov_base = hdr;
854 iov.iov_len = hdr->nlmsg_len;
855 memset(&msg, 0, sizeof(msg));
856 msg.msg_name = &snl;
857 msg.msg_namelen = sizeof(snl);
858 msg.msg_iov = &iov;
859 msg.msg_iovlen = 1;
860 /* Request a reply */
861 hdr->nlmsg_flags |= NLM_F_ACK;
862 hdr->nlmsg_seq = ++seq;
863
864 if (sendmsg(s, &msg, 0) != -1)
865 r = get_netlink(ctx, ifp, s, 0, callback);
866 else
867 r = -1;
868 close(s);
869 return r;
870}
871
872#define NLMSG_TAIL(nmsg) \
873 ((struct rtattr *)(((ptrdiff_t)(nmsg))+NLMSG_ALIGN((nmsg)->nlmsg_len)))
874
875static int
876add_attr_l(struct nlmsghdr *n, unsigned short maxlen, unsigned short type,
877 const void *data, unsigned short alen)
878{
879 unsigned short len = (unsigned short)RTA_LENGTH(alen);
880 struct rtattr *rta;
881
882 if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) {
883 errno = ENOBUFS;
884 return -1;
885 }
886
887 rta = NLMSG_TAIL(n);
888 rta->rta_type = type;
889 rta->rta_len = len;
890 if (alen)
891 memcpy(RTA_DATA(rta), data, alen);
892 n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len);
893
894 return 0;
895}
896
897static int
898add_attr_32(struct nlmsghdr *n, unsigned short maxlen, unsigned short type,
899 uint32_t data)
900{
901 unsigned short len = RTA_LENGTH(sizeof(data));
902 struct rtattr *rta;
903
904 if (NLMSG_ALIGN(n->nlmsg_len) + len > maxlen) {
905 errno = ENOBUFS;
906 return -1;
907 }
908
909 rta = NLMSG_TAIL(n);
910 rta->rta_type = type;
911 rta->rta_len = len;
912 memcpy(RTA_DATA(rta), &data, sizeof(data));
913 n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + len;
914
915 return 0;
916}
917
918#ifdef HAVE_NL80211_H
919static struct nlattr *
920nla_next(struct nlattr *nla, size_t *rem)
921{
922
923 *rem -= NLA_ALIGN(nla->nla_len);
924 return (struct nlattr *)(void *)((char *)nla + NLA_ALIGN(nla->nla_len));
925}
926
927#define NLA_TYPE(nla) ((nla)->nla_type & NLA_TYPE_MASK)
928#define NLA_LEN(nla) (unsigned int)((nla)->nla_len - NLA_HDRLEN)
929#define NLA_OK(nla, rem) \
930 ((rem) >= sizeof(struct nlattr) && \
931 (nla)->nla_len >= sizeof(struct nlattr) && \
932 (nla)->nla_len <= rem)
933#define NLA_DATA(nla) ((char *)(nla) + NLA_HDRLEN)
934#define NLA_FOR_EACH_ATTR(pos, head, len, rem) \
935 for (pos = head, rem = len; NLA_OK(pos, rem); pos = nla_next(pos, &(rem)))
936
937struct nlmg
938{
939 struct nlmsghdr hdr;
940 struct genlmsghdr ghdr;
941 char buffer[64];
942};
943
944static int
945nla_put_32(struct nlmsghdr *n, unsigned short maxlen,
946 unsigned short type, uint32_t data)
947{
948 unsigned short len;
949 struct nlattr *nla;
950
951 len = NLA_ALIGN(NLA_HDRLEN + sizeof(data));
952 if (NLMSG_ALIGN(n->nlmsg_len) + len > maxlen) {
953 errno = ENOBUFS;
954 return -1;
955 }
956
957 nla = (struct nlattr *)NLMSG_TAIL(n);
958 nla->nla_type = type;
959 nla->nla_len = len;
960 memcpy(NLA_DATA(nla), &data, sizeof(data));
961 n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + len;
962
963 return 0;
964}
965
966static int
967nla_put_string(struct nlmsghdr *n, unsigned short maxlen,
968 unsigned short type, const char *data)
969{
970 struct nlattr *nla;
971 size_t len, sl;
972
973 sl = strlen(data) + 1;
974 len = NLA_ALIGN(NLA_HDRLEN + sl);
975 if (NLMSG_ALIGN(n->nlmsg_len) + len > maxlen) {
976 errno = ENOBUFS;
977 return -1;
978 }
979
980 nla = (struct nlattr *)NLMSG_TAIL(n);
981 nla->nla_type = type;
982 nla->nla_len = (unsigned short)len;
983 memcpy(NLA_DATA(nla), data, sl);
984 n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + (unsigned short)len;
985 return 0;
986}
987
988static int
989gnl_parse(struct nlmsghdr *nlm, struct nlattr *tb[], int maxtype)
990{
991 struct genlmsghdr *ghdr;
992 struct nlattr *head, *nla;
993 size_t len, rem;
994 int type;
995
996 memset(tb, 0, sizeof(*tb) * ((unsigned int)maxtype + 1));
997 ghdr = NLMSG_DATA(nlm);
998 head = (struct nlattr *)(void *)((char *) ghdr + GENL_HDRLEN);
999 len = nlm->nlmsg_len - GENL_HDRLEN - NLMSG_HDRLEN;
1000 NLA_FOR_EACH_ATTR(nla, head, len, rem) {
1001 type = NLA_TYPE(nla);
1002 if (type > maxtype)
1003 continue;
1004 tb[type] = nla;
1005 }
1006 return 0;
1007}
1008
1009static int
1010_gnl_getfamily(__unused struct dhcpcd_ctx *ctx, __unused struct interface *ifp,
1011 struct nlmsghdr *nlm)
1012{
1013 struct nlattr *tb[CTRL_ATTR_FAMILY_ID + 1];
1014 uint16_t family;
1015
1016 if (gnl_parse(nlm, tb, CTRL_ATTR_FAMILY_ID) == -1)
1017 return -1;
1018 if (tb[CTRL_ATTR_FAMILY_ID] == NULL) {
1019 errno = ENOENT;
1020 return -1;
1021 }
1022 family = *(uint16_t *)(void *)NLA_DATA(tb[CTRL_ATTR_FAMILY_ID]);
1023 return (int)family;
1024}
1025
1026static int
1027gnl_getfamily(struct dhcpcd_ctx *ctx, const char *name)
1028{
1029 struct nlmg nlm;
1030
1031 memset(&nlm, 0, sizeof(nlm));
1032 nlm.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct genlmsghdr));
1033 nlm.hdr.nlmsg_type = GENL_ID_CTRL;
1034 nlm.hdr.nlmsg_flags = NLM_F_REQUEST;
1035 nlm.ghdr.cmd = CTRL_CMD_GETFAMILY;
1036 nlm.ghdr.version = 1;
1037 if (nla_put_string(&nlm.hdr, sizeof(nlm),
1038 CTRL_ATTR_FAMILY_NAME, name) == -1)
1039 return -1;
1040 return send_netlink(ctx, NULL, NETLINK_GENERIC, &nlm.hdr,
1041 &_gnl_getfamily);
1042}
1043
1044static int
1045_if_getssid(__unused struct dhcpcd_ctx *ctx, struct interface *ifp,
1046 struct nlmsghdr *nlm)
1047{
1048 struct nlattr *tb[NL80211_ATTR_SSID + 1];
1049
1050 if (gnl_parse(nlm, tb, NL80211_ATTR_SSID) == -1)
1051 return -1;
1052
1053 if (tb[NL80211_ATTR_SSID] == NULL) {
1054 /* If the SSID is not found then it means that
1055 * we're not associated to an AP. */
1056 ifp->ssid_len = 0;
1057 goto out;
1058 }
1059
1060 ifp->ssid_len = NLA_LEN(tb[NL80211_ATTR_SSID]);
1061 if (ifp->ssid_len > sizeof(ifp->ssid)) {
1062 errno = ENOBUFS;
1063 ifp->ssid_len = 0;
1064 return -1;
1065 }
1066 memcpy(ifp->ssid, NLA_DATA(tb[NL80211_ATTR_SSID]), ifp->ssid_len);
1067
1068out:
1069 ifp->ssid[ifp->ssid_len] = '\0';
1070 return (int)ifp->ssid_len;
1071}
1072
1073static int
1074if_getssid_nl80211(struct interface *ifp)
1075{
1076 int family;
1077 struct nlmg nlm;
1078
1079 errno = 0;
1080 family = gnl_getfamily(ifp->ctx, "nl80211");
1081 if (family == -1)
1082 return -1;
1083 memset(&nlm, 0, sizeof(nlm));
1084 nlm.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct genlmsghdr));
1085 nlm.hdr.nlmsg_type = (unsigned short)family;
1086 nlm.hdr.nlmsg_flags = NLM_F_REQUEST;
1087 nlm.ghdr.cmd = NL80211_CMD_GET_INTERFACE;
1088 nla_put_32(&nlm.hdr, sizeof(nlm), NL80211_ATTR_IFINDEX, ifp->index);
1089
1090 return send_netlink(ifp->ctx, ifp,
1091 NETLINK_GENERIC, &nlm.hdr, &_if_getssid);
1092}
1093#endif
1094
1095int
1096if_getssid(struct interface *ifp)
1097{
1098 int r;
1099
1100 r = if_getssid_wext(ifp->name, ifp->ssid);
1101 if (r != -1)
1102 ifp->ssid_len = (unsigned int)r;
1103#ifdef HAVE_NL80211_H
1104 else if (r == -1)
1105 r = if_getssid_nl80211(ifp);
1106#endif
1107 return r;
1108}
1109
1110struct nlma
1111{
1112 struct nlmsghdr hdr;
1113 struct ifaddrmsg ifa;
1114 char buffer[64];
1115};
1116
1117struct nlmr
1118{
1119 struct nlmsghdr hdr;
1120 struct rtmsg rt;
1121 char buffer[256];
1122};
1123
1124#ifdef INET
1125const char *if_pfname = "Packet Socket";
1126
1127int
1128if_openrawsocket(struct interface *ifp, uint16_t protocol)
1129{
1130 int s;
1131 union sockunion {
1132 struct sockaddr sa;
1133 struct sockaddr_ll sll;
1134 struct sockaddr_storage ss;
1135 } su;
1136 struct sock_fprog pf;
1137#ifdef PACKET_AUXDATA
1138 int n;
1139#endif
1140
1141#ifdef SOCK_CLOEXEC
1142 if ((s = socket(PF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
1143 htons(protocol))) == -1)
1144 return -1;
1145#else
1146 int flags;
1147
1148 if ((s = socket(PF_PACKET, SOCK_DGRAM, htons(protocol))) == -1)
1149 return -1;
1150 if ((flags = fcntl(s, F_GETFD, 0)) == -1 ||
1151 fcntl(s, F_SETFD, flags | FD_CLOEXEC) == -1)
1152 {
1153 close(s);
1154 return -1;
1155 }
1156 if ((flags = fcntl(s, F_GETFL, 0)) == -1 ||
1157 fcntl(s, F_SETFL, flags | O_NONBLOCK) == -1)
1158 {
1159 close(s);
1160 return -1;
1161 }
1162#endif
1163 /* Install the DHCP filter */
1164 memset(&pf, 0, sizeof(pf));
1165 if (protocol == ETHERTYPE_ARP) {
1166 pf.filter = UNCONST(arp_bpf_filter);
1167 pf.len = arp_bpf_filter_len;
1168 } else {
1169 pf.filter = UNCONST(dhcp_bpf_filter);
1170 pf.len = dhcp_bpf_filter_len;
1171 }
1172 if (setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, &pf, sizeof(pf)) != 0)
1173 goto eexit;
1174#ifdef PACKET_AUXDATA
1175 n = 1;
1176 if (setsockopt(s, SOL_PACKET, PACKET_AUXDATA, &n, sizeof(n)) != 0) {
1177 if (errno != ENOPROTOOPT)
1178 goto eexit;
1179 }
1180#endif
1181
1182 memset(&su, 0, sizeof(su));
1183 su.sll.sll_family = PF_PACKET;
1184 su.sll.sll_protocol = htons(protocol);
1185 su.sll.sll_ifindex = (int)ifp->index;
1186 if (bind(s, &su.sa, sizeof(su.sll)) == -1)
1187 goto eexit;
1188 return s;
1189
1190eexit:
1191 close(s);
1192 return -1;
1193}
1194
1195ssize_t
1196if_sendrawpacket(const struct interface *ifp, uint16_t protocol,
Samuel Tanf20514b2015-08-13 16:24:02 -07001197 const void *data, size_t len, const uint8_t *dest_hw_addr)
Samuel Tand7ed8512015-08-13 16:11:35 -07001198{
1199 const struct dhcp_state *state;
1200 union sockunion {
1201 struct sockaddr sa;
1202 struct sockaddr_ll sll;
1203 struct sockaddr_storage ss;
1204 } su;
1205 int fd;
1206
1207 memset(&su, 0, sizeof(su));
1208 su.sll.sll_family = AF_PACKET;
1209 su.sll.sll_protocol = htons(protocol);
1210 su.sll.sll_ifindex = (int)ifp->index;
1211 su.sll.sll_hatype = htons(ifp->family);
1212 su.sll.sll_halen = (unsigned char)ifp->hwlen;
1213 if (ifp->family == ARPHRD_INFINIBAND)
1214 memcpy(&su.sll.sll_addr,
1215 &ipv4_bcast_addr, sizeof(ipv4_bcast_addr));
Samuel Tanf20514b2015-08-13 16:24:02 -07001216 else {
1217 if (dest_hw_addr)
1218 memcpy(&su.sll.sll_addr, dest_hw_addr, ifp->hwlen);
1219 else
1220 memset(&su.sll.sll_addr, 0xff, ifp->hwlen);
1221 }
Samuel Tand7ed8512015-08-13 16:11:35 -07001222 state = D_CSTATE(ifp);
1223 if (protocol == ETHERTYPE_ARP)
1224 fd = state->arp_fd;
1225 else
1226 fd = state->raw_fd;
1227
1228 return sendto(fd, data, len, 0, &su.sa, sizeof(su.sll));
1229}
1230
1231ssize_t
1232if_readrawpacket(struct interface *ifp, uint16_t protocol,
1233 void *data, size_t len, int *flags)
1234{
1235 struct iovec iov = {
1236 .iov_base = data,
1237 .iov_len = len,
1238 };
1239 struct msghdr msg = {
1240 .msg_iov = &iov,
1241 .msg_iovlen = 1,
1242 };
1243 struct dhcp_state *state;
1244#ifdef PACKET_AUXDATA
1245 unsigned char cmsgbuf[CMSG_LEN(sizeof(struct tpacket_auxdata))];
1246 struct cmsghdr *cmsg;
1247 struct tpacket_auxdata *aux;
1248#endif
1249
1250 ssize_t bytes;
1251 int fd = -1;
1252
1253#ifdef PACKET_AUXDATA
1254 msg.msg_control = cmsgbuf;
1255 msg.msg_controllen = sizeof(cmsgbuf);
1256#endif
1257
1258 state = D_STATE(ifp);
1259 if (protocol == ETHERTYPE_ARP)
1260 fd = state->arp_fd;
1261 else
1262 fd = state->raw_fd;
1263 bytes = recvmsg(fd, &msg, 0);
1264 if (bytes == -1)
1265 return -1;
1266 *flags = RAW_EOF; /* We only ever read one packet */
1267 if (bytes) {
1268#ifdef PACKET_AUXDATA
1269 for (cmsg = CMSG_FIRSTHDR(&msg);
1270 cmsg;
1271 cmsg = CMSG_NXTHDR(&msg, cmsg))
1272 {
1273 if (cmsg->cmsg_level == SOL_PACKET &&
1274 cmsg->cmsg_type == PACKET_AUXDATA) {
1275 aux = (void *)CMSG_DATA(cmsg);
1276 if (aux->tp_status & TP_STATUS_CSUMNOTREADY)
1277 *flags |= RAW_PARTIALCSUM;
1278 }
1279 }
1280#endif
1281 }
1282 return bytes;
1283}
1284
1285int
1286if_address(const struct interface *iface,
1287 const struct in_addr *address, const struct in_addr *netmask,
1288 const struct in_addr *broadcast, int action)
1289{
1290 struct nlma nlm;
1291 int retval = 0;
1292
1293 memset(&nlm, 0, sizeof(nlm));
1294 nlm.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
1295 nlm.hdr.nlmsg_flags = NLM_F_REQUEST;
1296 if (action >= 0) {
1297 nlm.hdr.nlmsg_flags |= NLM_F_CREATE | NLM_F_REPLACE;
1298 nlm.hdr.nlmsg_type = RTM_NEWADDR;
1299 } else
1300 nlm.hdr.nlmsg_type = RTM_DELADDR;
1301 nlm.ifa.ifa_index = iface->index;
1302 nlm.ifa.ifa_family = AF_INET;
1303 nlm.ifa.ifa_prefixlen = inet_ntocidr(*netmask);
1304 /* This creates the aliased interface */
1305 add_attr_l(&nlm.hdr, sizeof(nlm), IFA_LABEL,
1306 iface->alias, (unsigned short)(strlen(iface->alias) + 1));
1307 add_attr_l(&nlm.hdr, sizeof(nlm), IFA_LOCAL,
1308 &address->s_addr, sizeof(address->s_addr));
1309 if (action >= 0 && broadcast)
1310 add_attr_l(&nlm.hdr, sizeof(nlm), IFA_BROADCAST,
1311 &broadcast->s_addr, sizeof(broadcast->s_addr));
1312
1313 if (send_netlink(iface->ctx, NULL, NETLINK_ROUTE, &nlm.hdr, NULL) == -1)
1314 retval = -1;
1315 return retval;
1316}
1317
1318int
1319if_route(unsigned char cmd, const struct rt *rt)
1320{
1321 struct nlmr nlm;
1322 int retval = 0;
1323 struct dhcp_state *state;
1324
1325 memset(&nlm, 0, sizeof(nlm));
1326 nlm.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
1327 switch (cmd) {
1328 case RTM_CHANGE:
1329 nlm.hdr.nlmsg_type = RTM_NEWROUTE;
1330 nlm.hdr.nlmsg_flags = NLM_F_CREATE | NLM_F_REPLACE;
1331 break;
1332 case RTM_ADD:
1333 nlm.hdr.nlmsg_type = RTM_NEWROUTE;
1334 nlm.hdr.nlmsg_flags = NLM_F_CREATE | NLM_F_EXCL;
1335 break;
1336 case RTM_DELETE:
1337 nlm.hdr.nlmsg_type = RTM_DELROUTE;
1338 break;
1339 }
1340 nlm.hdr.nlmsg_flags |= NLM_F_REQUEST;
1341 nlm.rt.rtm_family = AF_INET;
1342 nlm.rt.rtm_table = RT_TABLE_MAIN;
1343
1344 state = D_STATE(rt->iface);
1345 if (cmd == RTM_DELETE)
1346 nlm.rt.rtm_scope = RT_SCOPE_NOWHERE;
1347 else {
1348 /* We only change route metrics for kernel routes */
1349 if (rt->dest.s_addr ==
1350 (state->addr.s_addr & state->net.s_addr) &&
1351 rt->net.s_addr == state->net.s_addr)
1352 nlm.rt.rtm_protocol = RTPROT_KERNEL;
1353 else
1354 nlm.rt.rtm_protocol = RTPROT_BOOT;
1355 if (rt->iface->flags & IFF_LOOPBACK)
1356 nlm.rt.rtm_scope = RT_SCOPE_HOST;
1357 else if (rt->gate.s_addr == INADDR_ANY ||
1358 (rt->gate.s_addr == rt->dest.s_addr &&
1359 rt->net.s_addr == INADDR_BROADCAST))
1360 nlm.rt.rtm_scope = RT_SCOPE_LINK;
1361 else
1362 nlm.rt.rtm_scope = RT_SCOPE_UNIVERSE;
1363 nlm.rt.rtm_type = RTN_UNICAST;
1364 }
1365
1366 nlm.rt.rtm_dst_len = inet_ntocidr(rt->net);
1367 add_attr_l(&nlm.hdr, sizeof(nlm), RTA_DST,
1368 &rt->dest.s_addr, sizeof(rt->dest.s_addr));
1369 if (nlm.rt.rtm_protocol == RTPROT_KERNEL) {
1370 add_attr_l(&nlm.hdr, sizeof(nlm), RTA_PREFSRC,
1371 &state->addr.s_addr, sizeof(state->addr.s_addr));
1372 }
1373 /* If a host route then don't add the gateway */
1374 if ((cmd == RTM_ADD || cmd == RTM_CHANGE) &&
1375 rt->net.s_addr != INADDR_BROADCAST)
1376 add_attr_l(&nlm.hdr, sizeof(nlm), RTA_GATEWAY,
1377 &rt->gate.s_addr, sizeof(rt->gate.s_addr));
1378
1379 if (rt->gate.s_addr != htonl(INADDR_LOOPBACK))
1380 add_attr_32(&nlm.hdr, sizeof(nlm), RTA_OIF, rt->iface->index);
1381 if (rt->metric)
1382 add_attr_32(&nlm.hdr, sizeof(nlm), RTA_PRIORITY, rt->metric);
1383
1384 if (send_netlink(rt->iface->ctx, NULL,
1385 NETLINK_ROUTE, &nlm.hdr, NULL) == -1)
1386 retval = -1;
1387 return retval;
1388}
1389
1390static int
1391_if_initrt(struct dhcpcd_ctx *ctx, __unused struct interface *ifp,
1392 struct nlmsghdr *nlm)
1393{
1394 struct rt rt;
1395
1396 if (if_copyrt(ctx, &rt, nlm) == 0)
1397 ipv4_handlert(ctx, RTM_ADD, &rt);
1398 return 0;
1399}
1400
1401int
1402if_initrt(struct interface *ifp)
1403{
1404 struct nlmr nlm;
1405
1406 ipv4_freerts(ifp->ctx->ipv4_kroutes);
1407
1408 memset(&nlm, 0, sizeof(nlm));
1409 nlm.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
1410 nlm.hdr.nlmsg_type = RTM_GETROUTE;
1411 nlm.hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_MATCH;
1412 nlm.hdr.nlmsg_flags |= NLM_F_REQUEST;
1413 nlm.rt.rtm_family = AF_INET;
1414 nlm.rt.rtm_table = RT_TABLE_MAIN;
1415 add_attr_32(&nlm.hdr, sizeof(nlm), RTA_OIF, ifp->index);
1416
1417 return send_netlink(ifp->ctx, ifp,
1418 NETLINK_ROUTE, &nlm.hdr, &_if_initrt);
1419}
1420
1421int
1422if_addrflags(__unused const struct in_addr *addr,
1423 __unused const struct interface *ifp)
1424{
1425
1426 /* Linux has no support for IPv4 address flags */
1427 return 0;
1428}
1429#endif
1430
1431#ifdef INET6
1432int
1433if_address6(const struct ipv6_addr *ap, int action)
1434{
1435 struct nlma nlm;
1436 struct ifa_cacheinfo cinfo;
1437 int retval = 0;
1438/* IFA_FLAGS is not a define, but is was added at the same time
1439 * IFA_F_NOPREFIXROUTE was do use that. */
1440#if defined(IFA_F_NOPREFIXROUTE) || defined(IFA_F_MANAGETEMPADDR)
1441 uint32_t flags = 0;
1442#endif
1443
1444 memset(&nlm, 0, sizeof(nlm));
1445 nlm.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
1446 nlm.hdr.nlmsg_flags = NLM_F_REQUEST;
1447 if (action >= 0) {
1448 nlm.hdr.nlmsg_flags |= NLM_F_CREATE | NLM_F_REPLACE;
1449 nlm.hdr.nlmsg_type = RTM_NEWADDR;
1450 } else
1451 nlm.hdr.nlmsg_type = RTM_DELADDR;
1452 nlm.ifa.ifa_index = ap->iface->index;
1453 nlm.ifa.ifa_family = AF_INET6;
1454 if (ap->addr_flags & IFA_F_TEMPORARY) {
1455#ifdef IFA_F_NOPREFIXROUTE
1456 flags |= IFA_F_TEMPORARY;
1457#else
1458 nlm.ifa.ifa_flags |= IFA_F_TEMPORARY;
1459#endif
1460 }
1461#ifdef IFA_F_MANAGETEMPADDR
1462 else if (ap->flags & IPV6_AF_AUTOCONF &&
1463 ip6_use_tempaddr(ap->iface->name))
1464 flags |= IFA_F_MANAGETEMPADDR;
1465#endif
1466
1467 /* Add as /128 if no IFA_F_NOPREFIXROUTE ? */
1468 nlm.ifa.ifa_prefixlen = ap->prefix_len;
1469 /* This creates the aliased interface */
1470 add_attr_l(&nlm.hdr, sizeof(nlm), IFA_LABEL,
1471 ap->iface->alias, (unsigned short)(strlen(ap->iface->alias) + 1));
1472 add_attr_l(&nlm.hdr, sizeof(nlm), IFA_LOCAL,
1473 &ap->addr.s6_addr, sizeof(ap->addr.s6_addr));
1474
1475 if (action >= 0) {
1476 memset(&cinfo, 0, sizeof(cinfo));
1477 cinfo.ifa_prefered = ap->prefix_pltime;
1478 cinfo.ifa_valid = ap->prefix_vltime;
1479 add_attr_l(&nlm.hdr, sizeof(nlm), IFA_CACHEINFO,
1480 &cinfo, sizeof(cinfo));
1481 }
1482
1483#ifdef IFA_F_NOPREFIXROUTE
1484 if (!IN6_IS_ADDR_LINKLOCAL(&ap->addr))
1485 flags |= IFA_F_NOPREFIXROUTE;
1486#endif
1487#if defined(IFA_F_NOPREFIXROUTE) || defined(IFA_F_MANAGETEMPADDR)
1488 if (flags)
1489 add_attr_32(&nlm.hdr, sizeof(nlm), IFA_FLAGS, flags);
1490#endif
1491
1492 if (send_netlink(ap->iface->ctx, NULL, NETLINK_ROUTE, &nlm.hdr,
1493 NULL) == -1)
1494 retval = -1;
1495 return retval;
1496}
1497
1498static int
1499rta_add_attr_32(struct rtattr *rta, unsigned short maxlen,
1500 unsigned short type, uint32_t data)
1501{
1502 unsigned short len = RTA_LENGTH(sizeof(data));
1503 struct rtattr *subrta;
1504
1505 if (RTA_ALIGN(rta->rta_len) + len > maxlen) {
1506 errno = ENOBUFS;
1507 return -1;
1508 }
1509
1510 subrta = (struct rtattr*)(void *)
1511 (((char*)rta) + RTA_ALIGN(rta->rta_len));
1512 subrta->rta_type = type;
1513 subrta->rta_len = len;
1514 memcpy(RTA_DATA(subrta), &data, sizeof(data));
1515 rta->rta_len = (unsigned short)(NLMSG_ALIGN(rta->rta_len) + len);
1516 return 0;
1517}
1518
1519int
1520if_route6(unsigned char cmd, const struct rt6 *rt)
1521{
1522 struct nlmr nlm;
1523 int retval = 0;
1524
1525 memset(&nlm, 0, sizeof(nlm));
1526 nlm.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
1527 switch (cmd) {
1528 case RTM_CHANGE:
1529 nlm.hdr.nlmsg_type = RTM_NEWROUTE;
1530 nlm.hdr.nlmsg_flags = NLM_F_CREATE | NLM_F_REPLACE;
1531 break;
1532 case RTM_ADD:
1533 nlm.hdr.nlmsg_type = RTM_NEWROUTE;
1534 nlm.hdr.nlmsg_flags = NLM_F_CREATE | NLM_F_EXCL;
1535 break;
1536 case RTM_DELETE:
1537 nlm.hdr.nlmsg_type = RTM_DELROUTE;
1538 break;
1539 }
1540 nlm.hdr.nlmsg_flags |= NLM_F_REQUEST;
1541 nlm.rt.rtm_family = AF_INET6;
1542 nlm.rt.rtm_table = RT_TABLE_MAIN;
1543
1544 if (cmd == RTM_DELETE)
1545 nlm.rt.rtm_scope = RT_SCOPE_NOWHERE;
1546 else {
1547 /* None interface subnet routes are static. */
1548 if (rt->iface->flags & IFF_LOOPBACK)
1549 nlm.rt.rtm_scope = RT_SCOPE_HOST;
1550 else if (IN6_IS_ADDR_UNSPECIFIED(&rt->gate)) {
1551 nlm.rt.rtm_protocol = RTPROT_KERNEL;
1552 nlm.rt.rtm_scope = RT_SCOPE_LINK;
1553 } else
1554 nlm.rt.rtm_protocol = RTPROT_BOOT;
1555 if (rt->flags & RTF_REJECT)
1556 nlm.rt.rtm_type = RTN_UNREACHABLE;
1557 else
1558 nlm.rt.rtm_type = RTN_UNICAST;
1559 }
1560
1561 nlm.rt.rtm_dst_len = ipv6_prefixlen(&rt->net);
1562 add_attr_l(&nlm.hdr, sizeof(nlm), RTA_DST,
1563 &rt->dest.s6_addr, sizeof(rt->dest.s6_addr));
1564
1565 if (cmd == RTM_ADD && !IN6_IS_ADDR_UNSPECIFIED(&rt->gate))
1566 add_attr_l(&nlm.hdr, sizeof(nlm), RTA_GATEWAY,
1567 &rt->gate.s6_addr, sizeof(rt->gate.s6_addr));
1568
1569 if (!(rt->flags & RTF_REJECT)) {
1570 add_attr_32(&nlm.hdr, sizeof(nlm), RTA_OIF, rt->iface->index);
1571 if (rt->metric)
1572 add_attr_32(&nlm.hdr, sizeof(nlm),
1573 RTA_PRIORITY, rt->metric);
1574 }
1575 if (cmd == RTM_ADD && rt->mtu) {
1576 char metricsbuf[32];
1577 struct rtattr *metrics = (void *)metricsbuf;
1578
1579 metrics->rta_type = RTA_METRICS;
1580 metrics->rta_len = RTA_LENGTH(0);
1581 rta_add_attr_32(metrics, sizeof(metricsbuf), RTAX_MTU, rt->mtu);
1582 add_attr_l(&nlm.hdr, sizeof(nlm), RTA_METRICS,
1583 RTA_DATA(metrics), (unsigned short)RTA_PAYLOAD(metrics));
1584 }
1585
1586 if (send_netlink(rt->iface->ctx, NULL,
1587 NETLINK_ROUTE, &nlm.hdr, NULL) == -1)
1588 retval = -1;
1589 return retval;
1590}
1591
1592static int
1593_if_initrt6(struct dhcpcd_ctx *ctx, __unused struct interface *ifp,
1594 struct nlmsghdr *nlm)
1595{
1596 struct rt6 rt;
1597
1598 if (if_copyrt6(ctx, &rt, nlm) == 0)
1599 ipv6_handlert(ctx, RTM_ADD, &rt);
1600 return 0;
1601}
1602
1603int
1604if_initrt6(struct interface *ifp)
1605{
1606 struct nlmr nlm;
1607
1608 ipv6_freerts(&ifp->ctx->ipv6->kroutes);
1609
1610 memset(&nlm, 0, sizeof(nlm));
1611 nlm.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
1612 nlm.hdr.nlmsg_type = RTM_GETROUTE;
1613 nlm.hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_MATCH;
1614 nlm.hdr.nlmsg_flags |= NLM_F_REQUEST;
1615 nlm.rt.rtm_family = AF_INET6;
1616 nlm.rt.rtm_table = RT_TABLE_MAIN;
1617 add_attr_32(&nlm.hdr, sizeof(nlm), RTA_OIF, ifp->index);
1618
1619 return send_netlink(ifp->ctx, ifp,
1620 NETLINK_ROUTE, &nlm.hdr, &_if_initrt6);
1621}
1622
1623int
1624if_addrflags6(const struct in6_addr *addr, const struct interface *ifp)
1625{
1626 FILE *fp;
1627 char *p, ifaddress[33], address[33], name[IF_NAMESIZE + 1];
1628 unsigned int ifindex;
1629 int prefix, scope, flags, i;
1630
1631 fp = fopen(PROC_INET6, "r");
1632 if (fp == NULL)
1633 return -1;
1634
1635 p = ifaddress;
1636 for (i = 0; i < (int)sizeof(addr->s6_addr); i++) {
1637 p += snprintf(p, 3, "%.2x", addr->s6_addr[i]);
1638 }
1639 *p = '\0';
1640
1641 while (fscanf(fp, "%32[a-f0-9] %x %x %x %x %"TOSTRING(IF_NAMESIZE)"s\n",
1642 address, &ifindex, &prefix, &scope, &flags, name) == 6)
1643 {
1644 if (strlen(address) != 32) {
1645 fclose(fp);
1646 errno = ENOTSUP;
1647 return -1;
1648 }
1649 if (strcmp(name, ifp->name) == 0 &&
1650 strcmp(ifaddress, address) == 0)
1651 {
1652 fclose(fp);
1653 return flags;
1654 }
1655 }
1656
1657 fclose(fp);
1658 errno = ESRCH;
1659 return -1;
1660}
1661
1662int
1663if_getlifetime6(__unused struct ipv6_addr *ia)
1664{
1665
1666 /* God knows how to work out address lifetimes on Linux */
1667 errno = ENOTSUP;
1668 return -1;
1669}
1670
1671struct nlml
1672{
1673 struct nlmsghdr hdr;
1674 struct ifinfomsg i;
1675 char buffer[32];
1676};
1677
1678static int
1679add_attr_8(struct nlmsghdr *n, unsigned short maxlen, unsigned short type,
1680 uint8_t data)
1681{
1682
1683 return add_attr_l(n, maxlen, type, &data, sizeof(data));
1684}
1685
1686static struct rtattr *
1687add_attr_nest(struct nlmsghdr *n, unsigned short maxlen, unsigned short type)
1688{
1689 struct rtattr *nest;
1690
1691 nest = NLMSG_TAIL(n);
1692 add_attr_l(n, maxlen, type, NULL, 0);
1693 return nest;
1694}
1695
1696static void
1697add_attr_nest_end(struct nlmsghdr *n, struct rtattr *nest)
1698{
1699
1700 nest->rta_len = (unsigned short)((char *)NLMSG_TAIL(n) - (char *)nest);
1701}
1702
1703static int
1704if_disable_autolinklocal(struct dhcpcd_ctx *ctx, int ifindex)
1705{
1706 struct nlml nlm;
1707 struct rtattr *afs, *afs6;
1708
1709 memset(&nlm, 0, sizeof(nlm));
1710 nlm.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
1711 nlm.hdr.nlmsg_type = RTM_NEWLINK;
1712 nlm.hdr.nlmsg_flags = NLM_F_REQUEST;
1713 nlm.i.ifi_family = AF_INET6;
1714 nlm.i.ifi_index = ifindex;
1715 afs = add_attr_nest(&nlm.hdr, sizeof(nlm), IFLA_AF_SPEC);
1716 afs6 = add_attr_nest(&nlm.hdr, sizeof(nlm), AF_INET6);
1717 add_attr_8(&nlm.hdr, sizeof(nlm), IFLA_INET6_ADDR_GEN_MODE,
1718 IN6_ADDR_GEN_MODE_NONE);
1719 add_attr_nest_end(&nlm.hdr, afs6);
1720 add_attr_nest_end(&nlm.hdr, afs);
1721
1722 return send_netlink(ctx, NULL, NETLINK_ROUTE, &nlm.hdr, NULL);
1723}
1724
1725static const char *prefix = "/proc/sys/net/ipv6/conf";
1726
1727int
1728if_checkipv6(struct dhcpcd_ctx *ctx, const struct interface *ifp, int own)
1729{
1730 const char *ifname;
1731 int ra;
1732 char path[256];
1733
1734 if (ifp == NULL)
1735 ifname = "all";
1736 else if (own) {
1737 if (if_disable_autolinklocal(ctx, (int)ifp->index) == -1)
1738 logger(ctx, LOG_DEBUG,
1739 "%s: if_disable_autolinklocal: %m", ifp->name);
1740 }
1741 if (ifp)
1742 ifname = ifp->name;
1743
1744 snprintf(path, sizeof(path), "%s/%s/autoconf", prefix, ifname);
1745 ra = check_proc_int(path);
1746 if (ra != 1) {
1747 if (!own)
1748 logger(ctx, LOG_WARNING,
1749 "%s: IPv6 kernel autoconf disabled", ifname);
1750 } else if (ra != -1 && own) {
1751 if (write_path(path, "0") == -1) {
1752 logger(ctx, LOG_ERR, "write_path: %s: %m", path);
1753 return -1;
1754 }
1755 }
1756
1757 snprintf(path, sizeof(path), "%s/%s/accept_ra", prefix, ifname);
1758 ra = check_proc_int(path);
1759 if (ra == -1)
1760 /* The sysctl probably doesn't exist, but this isn't an
1761 * error as such so just log it and continue */
1762 logger(ctx, errno == ENOENT ? LOG_DEBUG : LOG_WARNING,
1763 "%s: %m", path);
1764 else if (ra != 0 && own) {
1765 logger(ctx, LOG_DEBUG, "%s: disabling kernel IPv6 RA support",
1766 ifname);
1767 if (write_path(path, "0") == -1) {
1768 logger(ctx, LOG_ERR, "write_path: %s: %m", path);
1769 return ra;
1770 }
1771 return 0;
1772 }
1773
1774 return ra;
1775}
1776
1777#ifdef IPV6_MANAGETEMPADDR
1778int
1779ip6_use_tempaddr(const char *ifname)
1780{
1781 char path[256];
1782 int val;
1783
1784 if (ifname == NULL)
1785 ifname = "all";
1786 snprintf(path, sizeof(path), "%s/%s/use_tempaddr", prefix, ifname);
1787 val = check_proc_int(path);
1788 return val == -1 ? 0 : val;
1789}
1790
1791int
1792ip6_temp_preferred_lifetime(const char *ifname)
1793{
1794 char path[256];
1795 int val;
1796
1797 if (ifname == NULL)
1798 ifname = "all";
1799 snprintf(path, sizeof(path), "%s/%s/temp_prefered_lft", prefix,
1800 ifname);
1801 val = check_proc_int(path);
1802 return val < 0 ? TEMP_PREFERRED_LIFETIME : val;
1803}
1804
1805int
1806ip6_temp_valid_lifetime(const char *ifname)
1807{
1808 char path[256];
1809 int val;
1810
1811 if (ifname == NULL)
1812 ifname = "all";
1813 snprintf(path, sizeof(path), "%s/%s/temp_valid_lft", prefix, ifname);
1814 val = check_proc_int(path);
1815 return val < 0 ? TEMP_VALID_LIFETIME : val;
1816}
1817#endif /* IPV6_MANAGETEMPADDR */
1818#endif /* INET6 */