New option to allow changing interface flags.
authormdw <mdw>
Mon, 19 Feb 2001 19:10:28 +0000 (19:10 +0000)
committermdw <mdw>
Mon, 19 Feb 2001 19:10:28 +0000 (19:10 +0000)
unet.c
unet.h
unetcfg.c

diff --git a/unet.c b/unet.c
index 7fdc317..3761138 100644 (file)
--- a/unet.c
+++ b/unet.c
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: unet.c,v 1.2 2001/02/03 18:39:59 mdw Exp $
+ * $Id: unet.c,v 1.3 2001/02/19 19:10:28 mdw Exp $
  *
  * User-space network device support.
  *
@@ -29,6 +29,9 @@
 /*----- Revision history --------------------------------------------------*
  *
  * $Log: unet.c,v $
+ * Revision 1.3  2001/02/19 19:10:28  mdw
+ * New option to allow changing interface flags.
+ *
  * Revision 1.2  2001/02/03 18:39:59  mdw
  * Setting the maximum interface count now does the right thing.
  *
@@ -377,7 +380,7 @@ static int unet_ifinit(struct device *nif)
   u->nif.rebuild_header = 0;
   u->nif.set_mac_address = 0;
 
-  u->nif.type = ARPHRD_LOOPBACK;       /* Got a better idea? */
+  u->nif.type = ARPHRD_TUNNEL;         /* Got a better idea? */
   u->nif.hard_header_len = 0;
   u->nif.mtu = 1500 - MAX_HEADER;
   u->nif.addr_len = 0;
@@ -963,6 +966,19 @@ static int unet_devioctl(struct inode *ino,
                unet_maxif); )
       break;
 
+    /* --- @UNIOCFIFFLAGS@ and @UNIOCSIFFLAGS@ --- */
+
+    case UNIOCGIFFLAGS:
+      D( printk(KERN_DEBUG "unet: UNIOCGIFFFLAGS\n"); )
+      e = u->nif.flags;
+      break;
+    case UNIOCSIFFLAGS:
+      D( printk(KERN_DEBUG "unet: UNIOCSIFFFLAGS: arg = %ld\n", arg); )
+      if ((u->nif.flags ^ arg) & ~IFF_VOLATILE)
+       return (-EINVAL);
+      u->nif.flags = arg;
+      break;
+
     /* --- Everything else --- *
      *
      * You lose.
diff --git a/unet.h b/unet.h
index 8609e5f..5854f9c 100644 (file)
--- a/unet.h
+++ b/unet.h
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: unet.h,v 1.1 2001/01/25 22:03:39 mdw Exp $
+ * $Id: unet.h,v 1.2 2001/02/19 19:10:28 mdw Exp $
  *
  * User-space network device support.
  *
@@ -29,6 +29,9 @@
 /*----- Revision history --------------------------------------------------*
  *
  * $Log: unet.h,v $
+ * Revision 1.2  2001/02/19 19:10:28  mdw
+ * New option to allow changing interface flags.
+ *
  * Revision 1.1  2001/01/25 22:03:39  mdw
  * Initial check-in (somewhat belated).
  *
@@ -151,6 +154,21 @@ struct unet_info {
 
 #define UNIOCSMAXIF _IO('U', 8)
 
+/* --- @UNIOCGIFFLAGS@ --- *
+ *
+ * Gets interface flags.  To complement @UNIOCSIFFLAGS@.
+ */
+
+#define UNIOCGIFFLAGS _IO('U', 9)
+
+/* --- @UNIOCSIFFLAGS@ --- *
+ *
+ * Sets interface flags.  This is required because there's no other sensible
+ * way to (e.g.) change the point-to-point flag.
+ */
+
+#define UNIOCSIFFLAGS _IO('U', 10)
+
 /*----- That's all, folks -------------------------------------------------*/
 
 #ifdef __cplusplus
index 4b98e0e..a51d452 100644 (file)
--- a/unetcfg.c
+++ b/unetcfg.c
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: unetcfg.c,v 1.2 2001/02/03 18:39:59 mdw Exp $
+ * $Id: unetcfg.c,v 1.3 2001/02/19 19:10:28 mdw Exp $
  *
  * User-space network device support.
  *
@@ -29,6 +29,9 @@
 /*----- Revision history --------------------------------------------------*
  *
  * $Log: unetcfg.c,v $
+ * Revision 1.3  2001/02/19 19:10:28  mdw
+ * New option to allow changing interface flags.
+ *
  * Revision 1.2  2001/02/03 18:39:59  mdw
  * Setting the maximum interface count now does the right thing.
  *
@@ -46,8 +49,6 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include <linux/if_ether.h>
-
 #include <sys/types.h>
 #include <sys/time.h>
 #include <sys/ioctl.h>
 #include <fcntl.h>
 #include <unistd.h>
 
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#include <linux/if.h>
+#include <linux/if_ether.h>
+
 #include "unet.h"
 
 /*----- Static variables --------------------------------------------------*/
@@ -527,6 +534,49 @@ static int cmd_maxif(char **av)
   return (run(av));
 }
 
+/* --- @cmd_ifflags@ --- */
+
+static int cmd_ifflags(char **av)
+{
+  static const struct iftab {
+    const char *name;
+    unsigned f;
+  } iftab[] = {
+    { "broadcast",     IFF_BROADCAST },
+    { "loopback",      IFF_LOOPBACK },
+    { "pointopoint",   IFF_POINTOPOINT },
+    { 0,               0 }
+  };
+
+  char *p;
+  int sense;
+  struct iftab *ift;
+  int f;
+
+  check();
+  if ((f = ioctl(fd, UNIOCGIFFLAGS)) < 0)
+    die("error reading interface flags: %s", strerror(errno));
+
+  for (p = strtok(*av++, ","); p; p = strtok(0, ",")) {
+    sense = 1;
+    switch (*p) {
+      case '-': sense = 0;
+      case '+':        p++;
+       break;
+    }
+    ift = LOOKUP(iftab, p);
+    if (!ift)
+      die("unknown interface flag `%s'", p);
+    if (sense)
+      f |= ift->f;
+    else
+      f &= ~ift->f;
+  }
+  if (ioctl(fd, UNIOCSIFFLAGS, f))
+    die("error setting interface flags: %s", strerror(errno));
+  return (run(av));
+}
+
 /* --- @run@ --- *
  *
  * Arguments:  @char **av@ = array of command line arguments
@@ -613,6 +663,12 @@ attachments inherit their debug flags from the global flag.\n\
 Configures the maximum number of interfaces allowed.\n\
 " },
 
+  { "ifflags", 1, cmd_ifflags,
+    "ifflags [-]FLAG,[-]FLAG,...", "set interface flags", "\
+Configures the network interface flags, because `ifconfig' is prevented\n\
+from doing the job properly.\n\
+" },
+
   { "help", 0, cmd_help,
     "help [COMMAND]", "display help about COMMAND", "\
 If COMMAND is given, display help about it.  If no COMAMND is specified,\n\
@@ -736,7 +792,7 @@ int main(int argc, char *argv[])
       { 0,                     0,      0,      0 }
     };
 
-    if ((i = getopt_long(argc, argv, "hVv", opt, 0)) < 0)
+    if ((i = getopt_long(argc, argv, "+hVv", opt, 0)) < 0)
       break;
     switch (i) {
       case 'h':