OSDN Git Service

v25
[android-x86/external-wireless-tools.git] / wireless_tools / sample_enc.c
diff --git a/wireless_tools/sample_enc.c b/wireless_tools/sample_enc.c
new file mode 100644 (file)
index 0000000..a1a90e2
--- /dev/null
@@ -0,0 +1,191 @@
+/* Note : this particular snipset of code is available under
+ * the LGPL, MPL or BSD license (at your choice).
+ * Jean II
+ */
+
+/* --------------------------- INCLUDE --------------------------- */
+
+#define MAX_KEY_SIZE   16
+#define        MAX_KEYS        8
+int    key_on = 0;
+int    key_open = 1;
+int    key_current = 0;
+char   key_table[MAX_KEYS][MAX_KEY_SIZE];
+int    key_size[MAX_KEYS];
+
+/* --------------------------- HANDLERS --------------------------- */
+
+static int ioctl_set_encode(struct net_device *dev,
+                           struct iw_request_info *info,
+                           struct iw_point *erq,
+                           char *key)
+{
+  int  index = (erq->flags & IW_ENCODE_INDEX) - 1;
+
+  if (erq->length > 0)
+    {
+      /* Check the size of the key */
+      if(erq->length > MAX_KEY_SIZE)
+       return(-EINVAL);
+
+      /* Check the index */
+      if((index < 0) || (index >= MAX_KEYS))
+       index = key_current;
+
+      /* Copy the key in the driver */
+      memcpy(key_table[index], key, erq->length);
+      key_size[index] = erq->length;
+      key_on = 1;
+    }
+  else
+    {
+      /* Do we want to just set the current key ? */
+      if((index >= 0) && (index < MAX_KEYS))
+       {
+         if(key_size[index] > 0)
+           {
+             key_current = index;
+             key_on = 1;
+           }
+         else
+           return(-EINVAL);
+       }
+    }
+
+  /* Read the flags */
+  if(erq->flags & IW_ENCODE_DISABLED)
+    key_on = 0;                /* disable encryption */
+  if(erq->flags & IW_ENCODE_RESTRICTED)
+    key_open = 0;      /* disable open mode */
+  if(erq->flags & IW_ENCODE_OPEN)
+    key_open = 1;      /* enable open mode */
+
+  return(0);
+}
+
+static int ioctl_get_encode(struct net_device *dev,
+                           struct iw_request_info *info,
+                           struct iw_point *erq,
+                           char *key)
+{
+  int  index = (erq->flags & IW_ENCODE_INDEX) - 1;
+
+  /* Set the flags */
+  erq->flags = 0;
+  if(key_on == 0)
+    erq->flags |= IW_ENCODE_DISABLED;
+  if(key_open == 0)
+    erq->flags |= IW_ENCODE_RESTRICTED;
+  else
+    erq->flags |= IW_ENCODE_OPEN;
+
+  /* Which key do we want */
+  if((index < 0) || (index >= MAX_KEYS))
+    index = key_current;
+  erq->flags |= index + 1;
+
+  /* Copy the key to the user buffer */
+  erq->length = key_size[index];
+  memcpy(key, key_table[index], key_size[index]);
+
+  return(0);
+}
+
+static int ioctl_get_range(struct net_device *dev,
+                          struct iw_request_info *info,
+                          struct iw_point *rrq,
+                          char *extra)
+{
+  struct iw_range *range = (struct iw_range *) extra;
+
+  rrq->length = sizeof(struct iw_range);
+
+  memset(range, 0, sizeof(struct iw_range));
+
+#if WIRELESS_EXT > 10
+  /* Version we are compiled with */
+  range->we_version_compiled = WIRELESS_EXT;
+  /* Minimum version we recommend */
+  range->we_version_source = 8;
+#endif /* WIRELESS_EXT > 10 */
+
+#if WIRELESS_EXT > 8
+  range->encoding_size[0] = 8; /* DES = 64 bits key */
+  range->encoding_size[1] = 16;
+  range->num_encoding_sizes = 2;
+  range->max_encoding_tokens = 8;
+#endif /* WIRELESS_EXT > 8 */
+  return(0);
+}
+
+/* --------------------------- BINDING --------------------------- */
+
+#if WIRELESS_EXT > 12
+static const iw_handler                handler_table[] =
+{
+       ...
+       (iw_handler) ioctl_set_encode,          /* SIOCSIWENCODE */
+       (iw_handler) ioctl_get_encode,          /* SIOCGIWENCODE */
+};
+#else  /* WIRELESS_EXT < 12 */
+static int
+do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+  struct iwreq *wrq = (struct iwreq *) ifr;
+  int          err = 0;
+
+  switch (cmd)
+    {
+#if WIRELESS_EXT > 8
+    case SIOCSIWENCODE:
+      {
+       char keybuf[MAX_KEY_SIZE];
+       if(wrq->u.encoding.pointer)
+         {
+           /* We actually have a key to set */
+           if(wrq->u.encoding.length > MAX_KEY_SIZE)
+             {
+               err = -E2BIG;
+               break;
+             }
+           if(copy_from_user(keybuf, wrq->u.encoding.pointer,
+                             wrq->u.encoding.length))
+             {
+               err = -EFAULT;
+               break;
+             }
+         }
+       else
+         if(wrq->u.encoding.length != 0)
+           {
+             err = -EINVAL;
+             break;
+           }
+       err = ioctl_set_encode(dev, NULL, &(wrq->u.encoding), keybuf);
+      }
+      break;
+
+    case SIOCGIWENCODE:
+      /* only super-user can see encryption key */
+      if(! capable(CAP_NET_ADMIN))
+       {
+         err = -EPERM;
+         break;
+       }
+      {
+       char keybuf[MAX_KEY_SIZE];
+       err = ioctl_get_encode(dev, NULL, &(wrq->u.encoding), keybuf);
+       if(wrq->u.encoding.pointer)
+         {
+           if (copy_to_user(wrq->u.encoding.pointer, keybuf,
+                            wrq->u.encoding.length))
+             err= -EFAULT;
+         }
+      }
+      break;
+#endif /* WIRELESS_EXT > 8 */
+    }
+  return(err);
+}
+#endif /* WIRELESS_EXT < 12 */
+