| @@ -1,16 +1,16 @@ | | | @@ -1,16 +1,16 @@ |
1 | /* $NetBSD: ifwatchd.c,v 1.44 2020/09/23 02:32:04 roy Exp $ */ | | 1 | /* $NetBSD: ifwatchd.c,v 1.45 2020/09/27 19:55:21 roy Exp $ */ |
2 | #include <sys/cdefs.h> | | 2 | #include <sys/cdefs.h> |
3 | __RCSID("$NetBSD: ifwatchd.c,v 1.44 2020/09/23 02:32:04 roy Exp $"); | | 3 | __RCSID("$NetBSD: ifwatchd.c,v 1.45 2020/09/27 19:55:21 roy Exp $"); |
4 | | | 4 | |
5 | /*- | | 5 | /*- |
6 | * Copyright (c) 2002, 2003 The NetBSD Foundation, Inc. | | 6 | * Copyright (c) 2002, 2003 The NetBSD Foundation, Inc. |
7 | * All rights reserved. | | 7 | * All rights reserved. |
8 | * | | 8 | * |
9 | * This code is derived from software contributed to The NetBSD Foundation | | 9 | * This code is derived from software contributed to The NetBSD Foundation |
10 | * by Martin Husemann <martin@NetBSD.org>. | | 10 | * by Martin Husemann <martin@NetBSD.org>. |
11 | * | | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | | 12 | * Redistribution and use in source and binary forms, with or without |
13 | * modification, are permitted provided that the following conditions | | 13 | * modification, are permitted provided that the following conditions |
14 | * are met: | | 14 | * are met: |
15 | * 1. Redistributions of source code must retain the above copyright | | 15 | * 1. Redistributions of source code must retain the above copyright |
16 | * notice, this list of conditions and the following disclaimer. | | 16 | * notice, this list of conditions and the following disclaimer. |
| @@ -29,27 +29,26 @@ __RCSID("$NetBSD: ifwatchd.c,v 1.44 2020 | | | @@ -29,27 +29,26 @@ __RCSID("$NetBSD: ifwatchd.c,v 1.44 2020 |
29 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 29 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
30 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 30 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
31 | * POSSIBILITY OF SUCH DAMAGE. | | 31 | * POSSIBILITY OF SUCH DAMAGE. |
32 | */ | | 32 | */ |
33 | | | 33 | |
34 | #include <sys/types.h> | | 34 | #include <sys/types.h> |
35 | #include <sys/param.h> | | 35 | #include <sys/param.h> |
36 | #include <sys/ioctl.h> | | 36 | #include <sys/ioctl.h> |
37 | #include <sys/socket.h> | | 37 | #include <sys/socket.h> |
38 | #include <sys/queue.h> | | 38 | #include <sys/queue.h> |
39 | #include <sys/wait.h> | | 39 | #include <sys/wait.h> |
40 | #include <net/if.h> | | 40 | #include <net/if.h> |
41 | #include <net/if_dl.h> | | 41 | #include <net/if_dl.h> |
42 | #include <net/if_media.h> | | | |
43 | #include <net/route.h> | | 42 | #include <net/route.h> |
44 | #include <netinet/in.h> | | 43 | #include <netinet/in.h> |
45 | #include <netinet/in_var.h> | | 44 | #include <netinet/in_var.h> |
46 | #include <arpa/inet.h> | | 45 | #include <arpa/inet.h> |
47 | | | 46 | |
48 | #include <paths.h> | | 47 | #include <paths.h> |
49 | #include <stdio.h> | | 48 | #include <stdio.h> |
50 | #include <stdlib.h> | | 49 | #include <stdlib.h> |
51 | #include <string.h> | | 50 | #include <string.h> |
52 | #include <unistd.h> | | 51 | #include <unistd.h> |
53 | #include <netdb.h> | | 52 | #include <netdb.h> |
54 | #include <err.h> | | 53 | #include <err.h> |
55 | #include <ifaddrs.h> | | 54 | #include <ifaddrs.h> |
| @@ -526,95 +525,61 @@ free_interfaces(void) | | | @@ -526,95 +525,61 @@ free_interfaces(void) |
526 | } | | 525 | } |
527 | | | 526 | |
528 | static struct interface_data * | | 527 | static struct interface_data * |
529 | find_interface(int idx) | | 528 | find_interface(int idx) |
530 | { | | 529 | { |
531 | struct interface_data * p; | | 530 | struct interface_data * p; |
532 | | | 531 | |
533 | SLIST_FOREACH(p, &ifs, next) | | 532 | SLIST_FOREACH(p, &ifs, next) |
534 | if (p->index == idx) | | 533 | if (p->index == idx) |
535 | return p; | | 534 | return p; |
536 | return NULL; | | 535 | return NULL; |
537 | } | | 536 | } |
538 | | | 537 | |
539 | static bool | | | |
540 | has_carrier(int s, const char *ifname) | | | |
541 | { | | | |
542 | struct ifmediareq ifmr = { .ifm_status = 0 }; | | | |
543 | | | | |
544 | strlcpy(ifmr.ifm_name, ifname, sizeof(ifmr.ifm_name)); | | | |
545 | if (ioctl(s, SIOCGIFMEDIA, &ifmr) == -1) { | | | |
546 | struct ifdatareq ifdr = { .ifdr_data.ifi_link_state = 0 }; | | | |
547 | | | | |
548 | strlcpy(ifdr.ifdr_name, ifname, sizeof(ifdr.ifdr_name)); | | | |
549 | if (ioctl(s, SIOCGIFDATA, &ifdr) == -1) { | | | |
550 | /* Should not be possible. */ | | | |
551 | return false; | | | |
552 | } | | | |
553 | if (ifdr.ifdr_data.ifi_link_state == LINK_STATE_UP) | | | |
554 | return true; | | | |
555 | else | | | |
556 | return false; | | | |
557 | } | | | |
558 | | | | |
559 | if (!(ifmr.ifm_status & IFM_AVALID)) { | | | |
560 | /* | | | |
561 | * Interface doesn't report media-valid status. | | | |
562 | * assume ok. | | | |
563 | */ | | | |
564 | return true; | | | |
565 | } | | | |
566 | | | | |
567 | if (ifmr.ifm_status & IFM_ACTIVE) | | | |
568 | return true; | | | |
569 | else | | | |
570 | return false; | | | |
571 | } | | | |
572 | | | | |
573 | static void | | 538 | static void |
574 | run_initial_ups(void) | | 539 | run_initial_ups(void) |
575 | { | | 540 | { |
576 | struct interface_data * ifd; | | 541 | struct interface_data * ifd; |
577 | struct ifaddrs *res = NULL, *p; | | 542 | struct ifaddrs *res = NULL, *p; |
578 | struct sockaddr *ifa; | | 543 | struct sockaddr *ifa; |
| | | 544 | const struct if_data *ifi; |
579 | int s, aflag; | | 545 | int s, aflag; |
580 | | | 546 | |
581 | s = socket(AF_INET, SOCK_DGRAM, 0); | | 547 | s = socket(AF_INET, SOCK_DGRAM, 0); |
582 | if (s < 0) | | 548 | if (s < 0) |
583 | return; | | 549 | return; |
584 | | | 550 | |
585 | if (getifaddrs(&res) != 0) | | 551 | if (getifaddrs(&res) != 0) |
586 | goto out; | | 552 | goto out; |
587 | | | 553 | |
588 | for (p = res; p; p = p->ifa_next) { | | 554 | for (p = res; p; p = p->ifa_next) { |
589 | SLIST_FOREACH(ifd, &ifs, next) { | | 555 | SLIST_FOREACH(ifd, &ifs, next) { |
590 | if (strcmp(ifd->ifname, p->ifa_name) == 0) | | 556 | if (strcmp(ifd->ifname, p->ifa_name) == 0) |
591 | break; | | 557 | break; |
592 | } | | 558 | } |
593 | if (ifd == NULL) | | 559 | if (ifd == NULL) |
594 | continue; | | 560 | continue; |
595 | | | 561 | |
596 | ifa = p->ifa_addr; | | 562 | ifa = p->ifa_addr; |
597 | if (ifa != NULL && ifa->sa_family == AF_LINK) | | 563 | if (ifa != NULL && ifa->sa_family == AF_LINK) |
598 | invoke_script(ifd->ifname, ARRIVAL, NULL, NULL); | | 564 | invoke_script(ifd->ifname, ARRIVAL, NULL, NULL); |
599 | | | 565 | |
600 | if ((p->ifa_flags & IFF_UP) == 0) | | 566 | if ((p->ifa_flags & IFF_UP) == 0) |
601 | continue; | | 567 | continue; |
602 | if (ifa == NULL) | | 568 | if (ifa == NULL) |
603 | continue; | | 569 | continue; |
604 | if (ifa->sa_family == AF_LINK) { | | 570 | if (ifa->sa_family == AF_LINK) { |
605 | if (has_carrier(s, ifd->ifname) == 0) { | | 571 | ifi = (const struct if_data *)p->ifa_data; |
| | | 572 | if (ifi->ifi_link_state == LINK_STATE_UP) |
606 | invoke_script(ifd->ifname, CARRIER, NULL, NULL); | | 573 | invoke_script(ifd->ifname, CARRIER, NULL, NULL); |
607 | ifd->last_carrier_status = | | 574 | ifd->last_carrier_status = ifi->ifi_link_state; |
608 | LINK_STATE_UP; | | | |
609 | } | | | |
610 | continue; | | 575 | continue; |
611 | } | | 576 | } |
612 | aflag = check_addrflags(ifa->sa_family, p->ifa_addrflags); | | 577 | aflag = check_addrflags(ifa->sa_family, p->ifa_addrflags); |
613 | if (aflag != READY) | | 578 | if (aflag != READY) |
614 | continue; | | 579 | continue; |
615 | invoke_script(ifd->ifname, UP, ifa, p->ifa_dstaddr); | | 580 | invoke_script(ifd->ifname, UP, ifa, p->ifa_dstaddr); |
616 | } | | 581 | } |
617 | freeifaddrs(res); | | 582 | freeifaddrs(res); |
618 | out: | | 583 | out: |
619 | close(s); | | 584 | close(s); |
620 | } | | 585 | } |