| @@ -1,16 +1,16 @@ | | | @@ -1,16 +1,16 @@ |
1 | /* $NetBSD: ifwatchd.c,v 1.38 2016/10/06 10:33:05 roy Exp $ */ | | 1 | /* $NetBSD: ifwatchd.c,v 1.39 2016/10/06 11:08:55 roy Exp $ */ |
2 | #include <sys/cdefs.h> | | 2 | #include <sys/cdefs.h> |
3 | __RCSID("$NetBSD: ifwatchd.c,v 1.38 2016/10/06 10:33:05 roy Exp $"); | | 3 | __RCSID("$NetBSD: ifwatchd.c,v 1.39 2016/10/06 11:08:55 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. |
| @@ -58,27 +58,26 @@ __RCSID("$NetBSD: ifwatchd.c,v 1.38 2016 | | | @@ -58,27 +58,26 @@ __RCSID("$NetBSD: ifwatchd.c,v 1.38 2016 |
58 | enum event { ARRIVAL, DEPARTURE, UP, DOWN, CARRIER, NO_CARRIER }; | | 58 | enum event { ARRIVAL, DEPARTURE, UP, DOWN, CARRIER, NO_CARRIER }; |
59 | enum addrflag { NOTREADY, DETACHED, READY }; | | 59 | enum addrflag { NOTREADY, DETACHED, READY }; |
60 | | | 60 | |
61 | /* local functions */ | | 61 | /* local functions */ |
62 | __dead static void usage(void); | | 62 | __dead static void usage(void); |
63 | static void dispatch(const void *, size_t); | | 63 | static void dispatch(const void *, size_t); |
64 | static enum addrflag check_addrflags(int af, int addrflags); | | 64 | static enum addrflag check_addrflags(int af, int addrflags); |
65 | static void check_addrs(const struct ifa_msghdr *ifam); | | 65 | static void check_addrs(const struct ifa_msghdr *ifam); |
66 | static void invoke_script(const char *ifname, enum event ev, | | 66 | static void invoke_script(const char *ifname, enum event ev, |
67 | const struct sockaddr *sa, const struct sockaddr *dst); | | 67 | const struct sockaddr *sa, const struct sockaddr *dst); |
68 | static void list_interfaces(const char *ifnames); | | 68 | static void list_interfaces(const char *ifnames); |
69 | static void check_announce(const struct if_announcemsghdr *ifan); | | 69 | static void check_announce(const struct if_announcemsghdr *ifan); |
70 | static void check_carrier(const struct if_msghdr *ifm); | | 70 | static void check_carrier(const struct if_msghdr *ifm); |
71 | static void rescan_interfaces(void); | | | |
72 | static void free_interfaces(void); | | 71 | static void free_interfaces(void); |
73 | static struct interface_data * find_interface(int index); | | 72 | static struct interface_data * find_interface(int index); |
74 | static void run_initial_ups(void); | | 73 | static void run_initial_ups(void); |
75 | | | 74 | |
76 | /* global variables */ | | 75 | /* global variables */ |
77 | static int verbose = 0, quiet = 0; | | 76 | static int verbose = 0, quiet = 0; |
78 | static int inhibit_initial = 0; | | 77 | static int inhibit_initial = 0; |
79 | static const char *arrival_script = NULL; | | 78 | static const char *arrival_script = NULL; |
80 | static const char *departure_script = NULL; | | 79 | static const char *departure_script = NULL; |
81 | static const char *up_script = NULL; | | 80 | static const char *up_script = NULL; |
82 | static const char *down_script = NULL; | | 81 | static const char *down_script = NULL; |
83 | static const char *carrier_script = NULL; | | 82 | static const char *carrier_script = NULL; |
84 | static const char *no_carrier_script = NULL; | | 83 | static const char *no_carrier_script = NULL; |
| @@ -247,27 +246,26 @@ static void | | | @@ -247,27 +246,26 @@ static void |
247 | dispatch(const void *msg, size_t len) | | 246 | dispatch(const void *msg, size_t len) |
248 | { | | 247 | { |
249 | const struct rt_msghdr *hd = msg; | | 248 | const struct rt_msghdr *hd = msg; |
250 | | | 249 | |
251 | if (hd->rtm_version != RTM_VERSION) | | 250 | if (hd->rtm_version != RTM_VERSION) |
252 | return; | | 251 | return; |
253 | | | 252 | |
254 | switch (hd->rtm_type) { | | 253 | switch (hd->rtm_type) { |
255 | case RTM_NEWADDR: | | 254 | case RTM_NEWADDR: |
256 | case RTM_DELADDR: | | 255 | case RTM_DELADDR: |
257 | check_addrs(msg); | | 256 | check_addrs(msg); |
258 | break; | | 257 | break; |
259 | case RTM_IFANNOUNCE: | | 258 | case RTM_IFANNOUNCE: |
260 | rescan_interfaces(); | | | |
261 | check_announce(msg); | | 259 | check_announce(msg); |
262 | break; | | 260 | break; |
263 | case RTM_IFINFO: | | 261 | case RTM_IFINFO: |
264 | check_carrier(msg); | | 262 | check_carrier(msg); |
265 | break; | | 263 | break; |
266 | case RTM_ADD: | | 264 | case RTM_ADD: |
267 | case RTM_DELETE: | | 265 | case RTM_DELETE: |
268 | case RTM_CHANGE: | | 266 | case RTM_CHANGE: |
269 | case RTM_LOSING: | | 267 | case RTM_LOSING: |
270 | case RTM_REDIRECT: | | 268 | case RTM_REDIRECT: |
271 | case RTM_MISS: | | 269 | case RTM_MISS: |
272 | case RTM_IEEE80211: | | 270 | case RTM_IEEE80211: |
273 | case RTM_ONEWADDR: | | 271 | case RTM_ONEWADDR: |
| @@ -493,55 +491,45 @@ check_carrier(const struct if_msghdr *if | | | @@ -493,55 +491,45 @@ check_carrier(const struct if_msghdr *if |
493 | | | 491 | |
494 | static void | | 492 | static void |
495 | check_announce(const struct if_announcemsghdr *ifan) | | 493 | check_announce(const struct if_announcemsghdr *ifan) |
496 | { | | 494 | { |
497 | struct interface_data * p; | | 495 | struct interface_data * p; |
498 | const char *ifname = ifan->ifan_name; | | 496 | const char *ifname = ifan->ifan_name; |
499 | | | 497 | |
500 | SLIST_FOREACH(p, &ifs, next) { | | 498 | SLIST_FOREACH(p, &ifs, next) { |
501 | if (strcmp(p->ifname, ifname) != 0) | | 499 | if (strcmp(p->ifname, ifname) != 0) |
502 | continue; | | 500 | continue; |
503 | | | 501 | |
504 | switch (ifan->ifan_what) { | | 502 | switch (ifan->ifan_what) { |
505 | case IFAN_ARRIVAL: | | 503 | case IFAN_ARRIVAL: |
| | | 504 | p->index = ifan->ifan_index; |
506 | invoke_script(p->ifname, ARRIVAL, NULL, NULL); | | 505 | invoke_script(p->ifname, ARRIVAL, NULL, NULL); |
507 | break; | | 506 | break; |
508 | case IFAN_DEPARTURE: | | 507 | case IFAN_DEPARTURE: |
| | | 508 | p->index = -1; |
| | | 509 | p->last_carrier_status = LINK_STATE_UNKNOWN; |
509 | invoke_script(p->ifname, DEPARTURE, NULL, NULL); | | 510 | invoke_script(p->ifname, DEPARTURE, NULL, NULL); |
510 | break; | | 511 | break; |
511 | default: | | 512 | default: |
512 | if (verbose) | | 513 | if (verbose) |
513 | (void) printf("unknown announce: " | | 514 | (void) printf("unknown announce: " |
514 | "what=%d\n", ifan->ifan_what); | | 515 | "what=%d\n", ifan->ifan_what); |
515 | break; | | 516 | break; |
516 | } | | 517 | } |
517 | return; | | 518 | return; |
518 | } | | 519 | } |
519 | } | | 520 | } |
520 | | | 521 | |
521 | static void | | 522 | static void |
522 | rescan_interfaces(void) | | | |
523 | { | | | |
524 | struct interface_data * p; | | | |
525 | | | | |
526 | SLIST_FOREACH(p, &ifs, next) { | | | |
527 | p->index = if_nametoindex(p->ifname); | | | |
528 | if (verbose) | | | |
529 | printf("interface \"%s\" has index %d\n", p->ifname, | | | |
530 | p->index); | | | |
531 | } | | | |
532 | } | | | |
533 | | | | |
534 | static void | | | |
535 | free_interfaces(void) | | 523 | free_interfaces(void) |
536 | { | | 524 | { |
537 | struct interface_data * p; | | 525 | struct interface_data * p; |
538 | | | 526 | |
539 | while (!SLIST_EMPTY(&ifs)) { | | 527 | while (!SLIST_EMPTY(&ifs)) { |
540 | p = SLIST_FIRST(&ifs); | | 528 | p = SLIST_FIRST(&ifs); |
541 | SLIST_REMOVE_HEAD(&ifs, next); | | 529 | SLIST_REMOVE_HEAD(&ifs, next); |
542 | free(p->ifname); | | 530 | free(p->ifname); |
543 | free(p); | | 531 | free(p); |
544 | } | | 532 | } |
545 | } | | 533 | } |
546 | | | 534 | |
547 | static struct interface_data * | | 535 | static struct interface_data * |