Subject: Re: ifwatcher written! [was Re: Getting laptop to auto-dhclient]
To: Todd Vierling <tv@duh.org>
From: Brian Grayson (home) <bgrayson@austin.rr.com>
List: netbsd-users
Date: 10/12/2003 12:41:29
--3V7upXqbjpZ4EhLz
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Sun, Oct 12, 2003 at 10:00:31AM -0400, Todd Vierling wrote:
> 
> If I'm reading the code correctly (which isn't guaranteed after how late I
> was up last night 8-), in ifwatchd.c:dispatch(), the arg "msg" should be
> castable to "struct if_msghdr".  From that, you can traverse to ifm_data, a
> "struct if_data", and look at ifi_link_state.  If it's changed from whatever
> value was last seen (LINK_STATE_{UNKNOWN,DOWN,UP}), you can do the
> appropriate action.

  Many thanks, Todd!  Here's a patch.  

  Todd (or anyone else who wants to review and try it out), if this looks
clean enough, let me know, and I can commit it when it's
appropriate.  I think it's too useful of a feature to not add!

  Brian

--3V7upXqbjpZ4EhLz
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="ifwatchd.patch"

Index: ifwatchd.c
===================================================================
RCS file: /cvsroot/src/usr.sbin/ifwatchd/ifwatchd.c,v
retrieving revision 1.16
diff -5 -u -p -t -r1.16 ifwatchd.c
--- ifwatchd.c	2003/07/04 14:11:36	1.16
+++ ifwatchd.c	2003/10/12 17:39:53
@@ -233,10 +233,13 @@ static void
 dispatch(void *msg, size_t len)
 {
         struct rt_msghdr *hd = msg;
         struct ifa_msghdr *ifam;
         enum event ev;
+        /* These are used only for the RTM_IFINFO case. */
+        struct if_msghdr *ifmp;
+        struct if_data ifdata;
 
         switch (hd->rtm_type) {
         case RTM_NEWADDR:
                 ev = UP;
                 goto work;
@@ -245,13 +248,30 @@ dispatch(void *msg, size_t len)
                 goto work;
         case RTM_IFANNOUNCE:
                 rescan_interfaces();
                 check_announce((struct if_announcemsghdr *)msg);
                 return;
+        case RTM_IFINFO:
+                ifmp = (struct if_msghdr*)msg;
+                ifdata = ifmp->ifm_data;
+                switch (ifdata.ifi_link_state) {
+                        case LINK_STATE_UP: ev = UP; break;
+                        case LINK_STATE_DOWN: ev = DOWN; break;
+                        default:
+                                if (verbose) {
+                                        printf("unknown link status ignored\n");
+                                        return;
+                                }
+                                break;
+                }
+                invoke_script(NULL, NULL, ev, ifmp->ifm_index, NULL);
+                return;
+
+                break;
         }
         if (verbose)
-                printf("unknown message ignored\n");
+                printf("unknown message ignored: rtm_type %d\n", hd->rtm_type);
         return;
 
 work:
         ifam = (struct ifa_msghdr *)msg;
         check_addrs((char *)(ifam + 1), ifam->ifam_addrs, ev);

--3V7upXqbjpZ4EhLz--