Commits

Bryan O'Sullivan committed 4a362d0

Add GPLv2 license header. Turn tabs into spaces.

Comments (0)

Files changed (9)

+/*
+ * config.c - manage configuration data
+ *
+ * Copyright 2003 Key Research, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.  You are
+ * forbidden from redistributing or modifying it under the terms of
+ * any other license, including other versions of the GNU General
+ * Public License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
 #include <ctype.h>
 #include <errno.h>
 #include <fnmatch.h>
     struct if_pat *pat;
 
     if (memo && fnmatch(memo->pat, name, 0) == 0) {
-	return 1;
+        return 1;
     }
-    
+
     for (pat = pats; pat != NULL; pat = pat->next) {
-	if (fnmatch(pat->pat, name, 0) == 0) {
-	    memo = pat;
-	    return 1;
-	}
+        if (fnmatch(pat->pat, name, 0) == 0) {
+            memo = pat;
+            return 1;
+        }
     }
 
     return 0;
     int len = strlen(name);
 
     if (len == 0) {
-	return 0;
+        return 0;
     }
 
     int x = fnmatch(name, "eth0", 0);
 
     if (x != 0 && x != FNM_NOMATCH) {
-	return -1;
+        return -1;
     }
-	
+
     struct if_pat *pat = xmalloc(sizeof(*pat));
 
     pat->pat = xmalloc(len + 1);
     FILE *fp;
 
     if (filename == NULL || strcmp(filename, "-") == 0) {
-	filename = "stdin";
-	fp = stdin;
+        filename = "stdin";
+        fp = stdin;
     } else if ((fp = fopen(filename, "r")) == NULL) {
-	do_log(LOG_ERR, "%s: %m", filename);
-	return;
+        do_log(LOG_ERR, "%s: %m", filename);
+        return;
     }
 
     char buf[8192];
 
     for (int line = 1; fgets(buf, sizeof(buf), fp); line++) {
-	char *l, *r;
+        char *l, *r;
 
-	for (l = buf; *l != '\0' && isspace(*l); l++) {
-	}
-	for (r = l; *r != '\0' && !isspace(*r); r++) {
-	}
+        for (l = buf; *l != '\0' && isspace(*l); l++) {
+        }
+        for (r = l; *r != '\0' && !isspace(*r); r++) {
+        }
 
-	*r = '\0';
+        *r = '\0';
 
-	char *h;
+        char *h;
 
-	if ((h = strchr(l, '#')) != NULL) {
-	    *h = '\0';
-	}
+        if ((h = strchr(l, '#')) != NULL) {
+            *h = '\0';
+        }
 
-	if (save_pattern(l) == -1) {
-	    do_log(LOG_ERR, "%s, line %d: bad pattern: %s",
-		   filename, line, l);
-	    exit(1);
-	}
+        if (save_pattern(l) == -1) {
+            do_log(LOG_ERR, "%s, line %d: bad pattern: %s",
+                   filename, line, l);
+            exit(1);
+        }
     }
-    
+
     if (ferror(fp)) {
-	do_log(LOG_ERR, "%s: %m", filename);
+        do_log(LOG_ERR, "%s: %m", filename);
     }
 
     if (fp != stdin) {
-	fclose(stdin);
+        fclose(stdin);
     }
 }
 
     static const char meta[] = "[]*?";
 
     for (char *x = s; *x != '\0'; x++) {
-	for (const char *m = meta; *m != '\0'; m++) {
-	    if (*x == *m) {
-		return x - s;
-	    }
-	}
+        for (const char *m = meta; *m != '\0'; m++) {
+            if (*x == *m) {
+                return x - s;
+            }
+        }
     }
 
     return -1;
 probe_interfaces(void)
 {
     int nmatch = 0;
-    
+
     for (struct if_pat *p = pats; p != NULL; p = p->next) {
-	int m;
-	
-	if ((m = has_meta(p->pat)) == -1) {
-	    nmatch += try_probe(p->pat);
-	}
-	else if (m == 0) {
-	    do_log(LOG_WARNING, "Don't know how to probe for interfaces "
-		   "matching %s", p->pat);
-	    continue;
-	}
-	else {
-	    char *z = xmalloc(m + 4);
-	    
-	    strncpy(z, p->pat, m);
-	    
-	    for (int i = 0; i < 16; i++) {
-		sprintf(z + m, "%d", i);
-		if (fnmatch(p->pat, z, 0) == 0) {
-		    nmatch += try_probe(z);
-		}
-	    }
+        int m;
 
-	    free(z);
-	}
+        if ((m = has_meta(p->pat)) == -1) {
+            nmatch += try_probe(p->pat);
+        }
+        else if (m == 0) {
+            do_log(LOG_WARNING, "Don't know how to probe for interfaces "
+                   "matching %s", p->pat);
+            continue;
+        }
+        else {
+            char *z = xmalloc(m + 4);
+
+            strncpy(z, p->pat, m);
+
+            for (int i = 0; i < 16; i++) {
+                sprintf(z + m, "%d", i);
+                if (fnmatch(p->pat, z, 0) == 0) {
+                    nmatch += try_probe(z);
+                }
+            }
+
+            free(z);
+        }
     }
 
     if (nmatch == 0) {
-	do_log(LOG_WARNING, "Could not probe for any interfaces");
+        do_log(LOG_WARNING, "Could not probe for any interfaces");
     }
 }
 
+/*
+ * if_info.c - track network interface information
+ *
+ * Copyright 2003 Key Research, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.  You are
+ * forbidden from redistributing or modifying it under the terms of
+ * any other license, including other versions of the GNU General
+ * Public License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
     memset(tb, 0, sizeof(tb) * (max + 1));
 
     while (RTA_OK(rta, len)) {
-	if (rta->rta_type <= max)
-	    tb[rta->rta_type] = rta;
-	rta = RTA_NEXT(rta,len);
+        if (rta->rta_type <= max)
+            tb[rta->rta_type] = rta;
+        rta = RTA_NEXT(rta,len);
     }
     if (len) {
-	do_log(LOG_ERR, "Badness! Deficit %d, rta_len=%d", len, rta->rta_len);
-	abort();
+        do_log(LOG_ERR, "Badness! Deficit %d, rta_len=%d", len, rta->rta_len);
+        abort();
     }
 }
 
 if_info_get_interface(struct nlmsghdr *hdr, struct rtattr *attrs[])
 {
     if (hdr->nlmsg_type != RTM_NEWLINK) {
-	return NULL;
+        return NULL;
     }
 
     struct ifinfomsg *info = NLMSG_DATA(hdr);
 
     if (hdr->nlmsg_len < NLMSG_LENGTH(sizeof(info))) {
-	return NULL;
+        return NULL;
     }
 
     if (attrs[IFLA_IFNAME] == NULL) {
-	return NULL;
+        return NULL;
     }
-    
+
     int x = info->ifi_index & 0xf;
     struct if_info *i, **ip;
 
     for (ip = &if_info[x]; (i = *ip) != NULL; ip = &i->next) {
-	if (i->index == info->ifi_index) {
-	    break;
-	}
+        if (i->index == info->ifi_index) {
+            break;
+        }
     }
-    
+
     if (i == NULL) {
-	i = xmalloc(sizeof(*i));
-	i->next = *ip;
-	i->index = info->ifi_index;
-	*ip = i;
+        i = xmalloc(sizeof(*i));
+        i->next = *ip;
+        i->index = info->ifi_index;
+        *ip = i;
     }
     return i;
 }
     struct if_info *i;
 
     if ((i = if_info_get_interface(hdr, attrs)) == NULL) {
-	return NULL;
+        return NULL;
     }
-    
+
     i->type = info->ifi_type;
     i->flags = info->ifi_flags;
 
     if (attrs[IFLA_ADDRESS]) {
-	int alen;
-	i->addr_len = alen = RTA_PAYLOAD(attrs[IFLA_ADDRESS]);
-	if (alen > sizeof(i->addr))
-	    alen = sizeof(i->addr);
-	memcpy(i->addr, RTA_DATA(attrs[IFLA_ADDRESS]), alen);
+        int alen;
+        i->addr_len = alen = RTA_PAYLOAD(attrs[IFLA_ADDRESS]);
+        if (alen > sizeof(i->addr))
+            alen = sizeof(i->addr);
+        memcpy(i->addr, RTA_DATA(attrs[IFLA_ADDRESS]), alen);
     } else {
-	i->addr_len = 0;
-	memset(i->addr, 0, sizeof(i->addr));
+        i->addr_len = 0;
+        memset(i->addr, 0, sizeof(i->addr));
     }
 
     strcpy(i->name, RTA_DATA(attrs[IFLA_IFNAME]));
-    
+
     return i;
 }
 
+/*
+ * lib.c - random library routines
+ *
+ * Copyright 2003 Key Research, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.  You are
+ * forbidden from redistributing or modifying it under the terms of
+ * any other license, including other versions of the GNU General
+ * Public License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
 #include <stdarg.h>
 #include <stdlib.h>
 #include <stdio.h>
     va_start(ap, fmt);
 
     if (use_syslog) {
-	vsyslog(pri, fmt, ap);
+        vsyslog(pri, fmt, ap);
     } else {
-	FILE *fp;
+        FILE *fp;
 
-	switch (pri) {
-	case LOG_INFO:
-	case LOG_NOTICE:
-	case LOG_DEBUG:
-	    fp = stdout;
-	    break;
-	default:
-	    fp = stderr;
-	    break;
-	}
-	
-	switch (pri) {
-	case LOG_WARNING:
-	    fputs("Warning: ", fp);
-	    break;
-	case LOG_NOTICE:
-	    fputs("Notice: ", fp);
-	    break;
-	case LOG_ERR:
-	    fputs("Error: ", fp);
-	    break;
-	case LOG_INFO:
-	case LOG_DEBUG:
-	    break;
-	default:
-	    fprintf(fp, "Log type %d: ", pri);
-	    break;
-	}
+        switch (pri) {
+        case LOG_INFO:
+        case LOG_NOTICE:
+        case LOG_DEBUG:
+            fp = stdout;
+            break;
+        default:
+            fp = stderr;
+            break;
+        }
 
-	vfprintf(fp, fmt, ap);
-	fputc('\n', fp);
+        switch (pri) {
+        case LOG_WARNING:
+            fputs("Warning: ", fp);
+            break;
+        case LOG_NOTICE:
+            fputs("Notice: ", fp);
+            break;
+        case LOG_ERR:
+            fputs("Error: ", fp);
+            break;
+        case LOG_INFO:
+        case LOG_DEBUG:
+            break;
+        default:
+            fprintf(fp, "Log type %d: ", pri);
+            break;
+        }
+
+        vfprintf(fp, fmt, ap);
+        fputc('\n', fp);
     }
 
     va_end(ap);
     pid_t pid;
 
     if ((pid = fork()) == -1) {
-	do_log(LOG_ERR, "fork: %m");
-	exit(1);
+        do_log(LOG_ERR, "fork: %m");
+        exit(1);
     }
     else if (pid != 0) {
-	return pid;
+        return pid;
     }
-    
+
     do_log(LOG_INFO, "%s %s %s", NP_SCRIPT, ifname, action);
-    
+
     execl(NP_SCRIPT, NP_SCRIPT, ifname, action, NULL);
 
     do_log(LOG_ERR, NP_SCRIPT ": %m");
     int status, ret;
 
     if ((ret = waitpid(pid, &status, 0)) == -1) {
-	do_log(LOG_ERR, "waitpid: %m");
-	exit(1);
+        do_log(LOG_ERR, "waitpid: %m");
+        exit(1);
     }
-    
+
     return WIFEXITED(status) ? WEXITSTATUS(status) : -WTERMSIG(status);
 }
 
     void *x = malloc(n);
 
     if (n > 0 && x == NULL) {
-	do_log(LOG_ERR, "malloc: %m");
-	exit(1);
+        do_log(LOG_ERR, "malloc: %m");
+        exit(1);
     }
 
     return x;
+/*
+ * main.c - daemon startup and link monitoring
+ *
+ * Copyright 2003 Key Research, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.  You are
+ * forbidden from redistributing or modifying it under the terms of
+ * any other license, including other versions of the GNU General
+ * Public License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
 #define _GNU_SOURCE
 #include <net/if.h>
 #include <stdio.h>
 
 
 #define flag_was_set(flag) \
-	(!(i->flags & (flag)) && (info->ifi_flags & (flag)))
+        (!(i->flags & (flag)) && (info->ifi_flags & (flag)))
 #define flag_was_unset(flag) \
-	((i->flags & (flag)) && !(info->ifi_flags & (flag)))
+        ((i->flags & (flag)) && !(info->ifi_flags & (flag)))
 
 static int
 handle_interface(struct nlmsghdr *hdr, void *arg)
 {
     if (hdr->nlmsg_type != RTM_NEWLINK && hdr->nlmsg_type != RTM_DELLINK) {
-	return 0;
+        return 0;
     }
-    
+
     struct ifinfomsg *info = NLMSG_DATA(hdr);
     int len = hdr->nlmsg_len - NLMSG_LENGTH(sizeof(*info));
 
     if (info->ifi_flags & IFF_LOOPBACK) {
-	goto done;
+        goto done;
     }
-    
+
     if (len < 0) {
-	return -1;
+        return -1;
     }
-    
+
     struct rtattr *attrs[IFLA_MAX + 1];
 
     parse_rtattrs(attrs, IFLA_MAX, IFLA_RTA(info), len);
 
     if (attrs[IFLA_IFNAME] == NULL) {
-	do_log(LOG_ERR, "No interface name");
-	exit(1);
+        do_log(LOG_ERR, "No interface name");
+        exit(1);
     }
-    
+
     struct if_info *i;
-    
+
     if ((i = if_info_get_interface(hdr, attrs)) == NULL) {
-	return -1;
+        return -1;
     }
 
     if (i->flags == info->ifi_flags) {
-	goto done;
+        goto done;
     }
-    
+
     char *name = RTA_DATA(attrs[IFLA_IFNAME]);
 
     if (!if_match(name)) {
-	goto done;
+        goto done;
     }
-    
+
     do_log(LOG_INFO, "%s: flags 0x%08x -> 0x%08x", name, i->flags,
-	   info->ifi_flags);
+           info->ifi_flags);
 
     if (flag_was_set(IFF_RUNNING)) {
-	run_netplug_bg(name, "in");
+        run_netplug_bg(name, "in");
     }
     if (flag_was_unset(IFF_RUNNING)) {
-	run_netplug_bg(name, "out");
+        run_netplug_bg(name, "out");
     }
     if (flag_was_unset(IFF_UP)) {
-	if (try_probe(name) == 0) {
-	    do_log(LOG_WARNING, "Could not bring %s back up", name);
-	}
+        if (try_probe(name) == 0) {
+            do_log(LOG_WARNING, "Could not bring %s back up", name);
+        }
     }
 
  done:
     if_info_update_interface(hdr, attrs);
-    
+
     return 0;
 }
 
     fprintf(stderr, "Usage: %s [-FPcip]\n", progname);
 
     fprintf(stderr, "\t-F\t\t"
-	    "run in foreground (don't become a daemon)\n");
+            "run in foreground (don't become a daemon)\n");
     fprintf(stderr, "\t-P\t\t"
-	    "do not autoprobe for interfaces (use with care)\n");
+            "do not autoprobe for interfaces (use with care)\n");
     fprintf(stderr, "\t-c config_file\t"
-	    "read interface patterns from this config file\n");
+            "read interface patterns from this config file\n");
     fprintf(stderr, "\t-i interface\t"
-	    "only handle interfaces matching this pattern\n");
+            "only handle interfaces matching this pattern\n");
     fprintf(stderr, "\t-p pid_file\t"
-	    "write daemon process ID to pid_file\n");
+            "write daemon process ID to pid_file\n");
 
     exit(exitcode);
 }
     FILE *fp;
 
     if ((fp = fopen(pid_file, "w")) == NULL) {
-	do_log(LOG_ERR, "%s: %m", pid_file);
-	return;
+        do_log(LOG_ERR, "%s: %m", pid_file);
+        return;
     }
-	    
+
     fprintf(fp, "%d\n", getpid());
     fclose(fp);
 }
     int c;
 
     while ((c = getopt(argc, argv, "FPc:hi:p:")) != EOF) {
-	switch (c) {
-	case 'F':
-	    foreground = 1;
-	    break;
-	case 'P':
-	    probe = 0;
-	    break;
-	case 'c':
-	    read_config(optarg);
-	    cfg_read = 1;
-	    break;
-	case 'h':
-	    usage(argv[0], 0);
-	    break;
-	case 'i':
-	    if (save_pattern(optarg) == -1) {
-		fprintf(stderr, "Bad pattern for '-i %s'\n", optarg);
-		exit(1);
-	    }
-	    break;
-	case 'p':
-	    pid_file = optarg;
-	    break;
-	case '?':
-	    usage(argv[0], 1);
-	}
+        switch (c) {
+        case 'F':
+            foreground = 1;
+            break;
+        case 'P':
+            probe = 0;
+            break;
+        case 'c':
+            read_config(optarg);
+            cfg_read = 1;
+            break;
+        case 'h':
+            usage(argv[0], 0);
+            break;
+        case 'i':
+            if (save_pattern(optarg) == -1) {
+                fprintf(stderr, "Bad pattern for '-i %s'\n", optarg);
+                exit(1);
+            }
+            break;
+        case 'p':
+            pid_file = optarg;
+            break;
+        case '?':
+            usage(argv[0], 1);
+        }
     }
-    
+
     if (!cfg_read) {
-	read_config(NP_ETC_DIR "/netplugd.conf");
+        read_config(NP_ETC_DIR "/netplugd.conf");
     }
-    
+
     if (getuid() != 0) {
-	do_log(LOG_WARNING, "This daemon will not work properly unless "
-	       "run by root");
+        do_log(LOG_WARNING, "This daemon will not work properly unless "
+               "run by root");
     }
-    
+
     if (probe) {
-	probe_interfaces();
+        probe_interfaces();
     }
-    
+
     if (!foreground) {
-	if (daemon(0, 0) == -1) {
-	    do_log(LOG_ERR, "daemon: %m");
-	    exit(1);
-	}
-	use_syslog = 1;
-	openlog("netplugd", LOG_PID, LOG_DAEMON);
+        if (daemon(0, 0) == -1) {
+            do_log(LOG_ERR, "daemon: %m");
+            exit(1);
+        }
+        use_syslog = 1;
+        openlog("netplugd", LOG_PID, LOG_DAEMON);
 
-	if (pid_file) {
-	    write_pid(pid_file);
-	}
+        if (pid_file) {
+            write_pid(pid_file);
+        }
     }
-    
+
     int fd = netlink_open();
 
     netlink_request_dump(fd);
+/*
+ * netlink.c - interface with kernel's netlink facility
+ *
+ * Copyright 2003 Key Research, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.  You are
+ * forbidden from redistributing or modifying it under the terms of
+ * any other license, including other versions of the GNU General
+ * Public License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * Portions of this file are based on code from Alexey Kuznetsov's
+ * iproute2 package.
+ */
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 netlink_request_dump(int fd)
 {
     struct {
-	struct nlmsghdr hdr;
-	struct rtgenmsg msg;
+        struct nlmsghdr hdr;
+        struct rtgenmsg msg;
     } req;
     struct sockaddr_nl addr;
 
 
     req.hdr.nlmsg_len = sizeof(req);
     req.hdr.nlmsg_type = RTM_GETLINK;
-    req.hdr.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST;
+    req.hdr.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
     req.hdr.nlmsg_pid = 0;
     req.hdr.nlmsg_seq = dump = ++seq;
     req.msg.rtgen_family = AF_UNSPEC;
 
     if (sendto(fd, (void*) &req, sizeof(req), 0,
-	       (struct sockaddr *) &addr, sizeof(addr)) == -1) {
-	do_log(LOG_ERR, "Could not request interface dump: %m");
-	exit(1);
+               (struct sockaddr *) &addr, sizeof(addr)) == -1) {
+        do_log(LOG_ERR, "Could not request interface dump: %m");
+        exit(1);
     }
 }
 
 
-void netlink_listen(int fd, netlink_callback callback, void *arg)
+void
+netlink_listen(int fd, netlink_callback callback, void *arg)
 {
     char   buf[8192];
     struct iovec iov = { buf, sizeof(buf) };
     struct sockaddr_nl addr;
     struct msghdr msg = {
-	.msg_name    = (void *) &addr,
-	.msg_namelen = sizeof(addr),
-	.msg_iov     = &iov,
-	.msg_iovlen  = 1,
+        .msg_name    = (void *) &addr,
+        .msg_namelen = sizeof(addr),
+        .msg_iov     = &iov,
+        .msg_iovlen  = 1,
     };
 
     memset(&addr, 0, sizeof(addr));
     addr.nl_groups = 0;
 
     while (1) {
-	int status = recvmsg(fd, &msg, 0);
+        int status = recvmsg(fd, &msg, 0);
 
-	if (status == -1) {
-	    if (errno == EINTR)
-		continue;
-	    do_log(LOG_ERR, "OVERRUN: %m");
-	    continue;
-	}
-	else if (status == 0) {
-	    do_log(LOG_ERR, "Unexpected EOF on netlink");
-	    exit(1);
-	}
+        if (status == -1) {
+            if (errno == EINTR)
+                continue;
+            do_log(LOG_ERR, "OVERRUN: %m");
+            continue;
+        }
+        else if (status == 0) {
+            do_log(LOG_ERR, "Unexpected EOF on netlink");
+            exit(1);
+        }
 
-	if (msg.msg_namelen != sizeof(addr)) {
-	    do_log(LOG_ERR, "Unexpected sender address length");
-	    exit(1);
-	}
+        if (msg.msg_namelen != sizeof(addr)) {
+            do_log(LOG_ERR, "Unexpected sender address length");
+            exit(1);
+        }
 
-	struct nlmsghdr *hdr;
-	
-	for (hdr = (struct nlmsghdr*)buf; status >= sizeof(*hdr); ) {
-	    int len = hdr->nlmsg_len;
-	    int l = len - sizeof(*hdr);
+        struct nlmsghdr *hdr;
 
-	    if (l < 0 || len > status) {
-		if (msg.msg_flags & MSG_TRUNC) {
-		    do_log(LOG_ERR, "Truncated message");
-		    exit(1);
-		}
-		do_log(LOG_ERR, "Malformed netlink message");
-		exit(1);
-	    }
+        for (hdr = (struct nlmsghdr*)buf; status >= sizeof(*hdr); ) {
+            int len = hdr->nlmsg_len;
+            int l = len - sizeof(*hdr);
 
-	    if (callback) {
-		int err;
-		
-		if ((err = callback(hdr, arg)) == -1) {
-		    return;
-		}
-	    }
+            if (l < 0 || len > status) {
+                if (msg.msg_flags & MSG_TRUNC) {
+                    do_log(LOG_ERR, "Truncated message");
+                    exit(1);
+                }
+                do_log(LOG_ERR, "Malformed netlink message");
+                exit(1);
+            }
 
-	    status -= NLMSG_ALIGN(len);
-	    hdr = (struct nlmsghdr *) ((char *) hdr + NLMSG_ALIGN(len));
-	}
-	if (msg.msg_flags & MSG_TRUNC) {
-	    do_log(LOG_ERR, "Message truncated");
-	    continue;
-	}
-	if (status) {
-	    do_log(LOG_ERR, "!!!Remnant of size %d", status);
-	    exit(1);
-	}
+            if (callback) {
+                int err;
+
+                if ((err = callback(hdr, arg)) == -1) {
+                    return;
+                }
+            }
+
+            status -= NLMSG_ALIGN(len);
+            hdr = (struct nlmsghdr *) ((char *) hdr + NLMSG_ALIGN(len));
+        }
+        if (msg.msg_flags & MSG_TRUNC) {
+            do_log(LOG_ERR, "Message truncated");
+            continue;
+        }
+        if (status) {
+            do_log(LOG_ERR, "!!!Remnant of size %d", status);
+            exit(1);
+        }
     }
 }
 
 
-void netlink_receive_dump(int fd, netlink_callback callback, void *arg)
+void
+netlink_receive_dump(int fd, netlink_callback callback, void *arg)
 {
     char buf[8192];
     struct sockaddr_nl addr;
     struct iovec iov = { buf, sizeof(buf) };
     struct msghdr msg = {
-	.msg_name	 = (void *) &addr,
-	.msg_namelen = sizeof(addr),
-	.msg_iov     = &iov,
-	.msg_iovlen  = 1,
+        .msg_name        = (void *) &addr,
+        .msg_namelen = sizeof(addr),
+        .msg_iov     = &iov,
+        .msg_iovlen  = 1,
     };
 
     while (1) {
-	int status = recvmsg(fd, &msg, 0);
+        int status = recvmsg(fd, &msg, 0);
 
-	if (status == -1) {
-	    if (errno == EINTR) {
-		continue;
-	    }
-	    do_log(LOG_ERR, "Netlink overrun: %m");
-	    continue;
-	}
-	else if (status == 0) {
-	    do_log(LOG_ERR, "Unexpected EOF on netlink");
-	    exit(1);
-	}
+        if (status == -1) {
+            if (errno == EINTR) {
+                continue;
+            }
+            do_log(LOG_ERR, "Netlink overrun: %m");
+            continue;
+        }
+        else if (status == 0) {
+            do_log(LOG_ERR, "Unexpected EOF on netlink");
+            exit(1);
+        }
 
-	if (msg.msg_namelen != sizeof(addr)) {
-	    do_log(LOG_ERR, "Unexpected sender address length");
-	    exit(1);
-	}
+        if (msg.msg_namelen != sizeof(addr)) {
+            do_log(LOG_ERR, "Unexpected sender address length");
+            exit(1);
+        }
 
-	struct nlmsghdr *hdr = (struct nlmsghdr *) buf;
+        struct nlmsghdr *hdr = (struct nlmsghdr *) buf;
 
-	while (NLMSG_OK(hdr, status)) {
-	    int err;
+        while (NLMSG_OK(hdr, status)) {
+            int err;
 
-	    if (hdr->nlmsg_seq != dump) {
-		do_log(LOG_ERR, "Skipping junk");
-		goto skip_it;
-	    }
+            if (hdr->nlmsg_seq != dump) {
+                do_log(LOG_ERR, "Skipping junk");
+                goto skip_it;
+            }
 
-	    if (hdr->nlmsg_type == NLMSG_DONE) {
-		return;
-	    }
-	    else if (hdr->nlmsg_type == NLMSG_ERROR) {
-		struct nlmsgerr *err = (struct nlmsgerr *) NLMSG_DATA(hdr);
-		
-		if (hdr->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr))) {
-		    do_log(LOG_ERR, "Netlink message truncated");
-		} else {
-		    errno = -err->error;
-		    do_log(LOG_ERR, "Error from rtnetlink: %m");
-		}
-		exit(1);
-	    }
+            if (hdr->nlmsg_type == NLMSG_DONE) {
+                return;
+            }
+            else if (hdr->nlmsg_type == NLMSG_ERROR) {
+                struct nlmsgerr *err = (struct nlmsgerr *) NLMSG_DATA(hdr);
 
-	    if (callback) {
-		if ((err = callback(hdr, arg)) == -1) {
-		    return;
-		}
-	    }
+                if (hdr->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr))) {
+                    do_log(LOG_ERR, "Netlink message truncated");
+                } else {
+                    errno = -err->error;
+                    do_log(LOG_ERR, "Error from rtnetlink: %m");
+                }
+                exit(1);
+            }
 
-	skip_it:
-	    hdr = NLMSG_NEXT(hdr, status);
-	}
-	if (msg.msg_flags & MSG_TRUNC) {
-	    do_log(LOG_ERR, "Message truncated");
-	    continue;
-	}
-	if (status) {
-	    do_log(LOG_ERR, "Dangling remnant of size %d!", status);
-	    exit(1);
-	}
+            if (callback) {
+                if ((err = callback(hdr, arg)) == -1) {
+                    return;
+                }
+            }
+
+        skip_it:
+            hdr = NLMSG_NEXT(hdr, status);
+        }
+        if (msg.msg_flags & MSG_TRUNC) {
+            do_log(LOG_ERR, "Message truncated");
+            continue;
+        }
+        if (status) {
+            do_log(LOG_ERR, "Dangling remnant of size %d!", status);
+            exit(1);
+        }
     }
 }
 
     int fd;
 
     if ((fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) == -1) {
-	do_log(LOG_ERR, "Could not create netlink socket: %m");
-	exit(1);
+        do_log(LOG_ERR, "Could not create netlink socket: %m");
+        exit(1);
     }
 
     struct sockaddr_nl addr;
     addr.nl_groups = RTMGRP_LINK;
 
     if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) {
-	do_log(LOG_ERR, "Could not bind netlink socket: %m");
-	exit(1);
+        do_log(LOG_ERR, "Could not bind netlink socket: %m");
+        exit(1);
     }
-    
+
     int addr_len = sizeof(addr);
-    
+
     if (getsockname(fd, (struct sockaddr *) &addr, &addr_len) == -1) {
-	do_log(LOG_ERR, "Could not get socket details: %m");
-	exit(1);
+        do_log(LOG_ERR, "Could not get socket details: %m");
+        exit(1);
     }
-	
+
     if (addr_len != sizeof(addr)) {
-	do_log(LOG_ERR, "Our netlink socket size does not match the kernel's!");
-	exit(1);
+        do_log(LOG_ERR, "Our netlink socket size does not match the kernel's!");
+        exit(1);
     }
 
     if (addr.nl_family != AF_NETLINK) {
-	do_log(LOG_ERR, "The kernel has given us an insane address family!");
-	exit(1);
+        do_log(LOG_ERR, "The kernel has given us an insane address family!");
+        exit(1);
     }
 
     return fd;
+/*
+ * netplug.h - common include file
+ *
+ * Copyright 2003 Key Research, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.  You are
+ * forbidden from redistributing or modifying it under the terms of
+ * any other license, including other versions of the GNU General
+ * Public License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
 #ifndef __netplug_h
 #define __netplug_h
 
 };
 
 struct if_info *if_info_get_interface(struct nlmsghdr *hdr,
-				      struct rtattr *attrs[]);
+                                      struct rtattr *attrs[]);
 struct if_info *if_info_update_interface(struct nlmsghdr *hdr,
-					 struct rtattr *attrs[]);
+                                         struct rtattr *attrs[]);
 int if_info_save_interface(struct nlmsghdr *hdr, void *arg);
 void parse_rtattrs(struct rtattr *tb[], int max, struct rtattr *rta, int len);
 
 Group: System Environment/Base
 URL: http://www.serpentine.com/~bos/netplug
 Packager: Bryan O'Sullivan <bos@serpentine.com>
+Vendor: Key Research, Inc. <http://www.keyresearch.com/>
 Source: %{name}-%{version}.tar.bz2
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot
 Requires: iproute >= 2.4.7
 #!/bin/sh
+#
+# netplug - policy agent for netplugd
+#
+# Copyright 2003 Key Research, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License, version 2, as
+# published by the Free Software Foundation.  You are forbidden from
+# redistributing or modifying it under the terms of any other license,
+# including other versions of the GNU General Public License.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+
 
 PATH=/usr/bin:/bin:/usr/sbin:/sbin
 export PATH

scripts/rc.netplugd

 # processname: netplugd
 # pidfile: /var/run/netplugd.pid
 
+# Copyright 2003 Key Research, Inc.
+
 # Source function library.
 . /etc/rc.d/init.d/functions