sample_enc.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /* Note : this particular snipset of code is available under
  2. * the LGPL, MPL or BSD license (at your choice).
  3. * Jean II
  4. */
  5. /* --------------------------- INCLUDE --------------------------- */
  6. #define MAX_KEY_SIZE 16
  7. #define MAX_KEYS 8
  8. int key_on = 0;
  9. int key_open = 1;
  10. int key_current = 0;
  11. char key_table[MAX_KEYS][MAX_KEY_SIZE];
  12. int key_size[MAX_KEYS];
  13. /* --------------------------- HANDLERS --------------------------- */
  14. static int ioctl_set_encode(struct net_device *dev,
  15. struct iw_request_info *info,
  16. struct iw_point *erq,
  17. char *key)
  18. {
  19. int index = (erq->flags & IW_ENCODE_INDEX) - 1;
  20. if (erq->length > 0)
  21. {
  22. /* Check the size of the key */
  23. if(erq->length > MAX_KEY_SIZE)
  24. return(-EINVAL);
  25. /* Check the index */
  26. if((index < 0) || (index >= MAX_KEYS))
  27. index = key_current;
  28. /* Copy the key in the driver */
  29. memcpy(key_table[index], key, erq->length);
  30. key_size[index] = erq->length;
  31. key_on = 1;
  32. }
  33. else
  34. {
  35. /* Do we want to just set the current key ? */
  36. if((index >= 0) && (index < MAX_KEYS))
  37. {
  38. if(key_size[index] > 0)
  39. {
  40. key_current = index;
  41. key_on = 1;
  42. }
  43. else
  44. return(-EINVAL);
  45. }
  46. }
  47. /* Read the flags */
  48. if(erq->flags & IW_ENCODE_DISABLED)
  49. key_on = 0; /* disable encryption */
  50. if(erq->flags & IW_ENCODE_RESTRICTED)
  51. key_open = 0; /* disable open mode */
  52. if(erq->flags & IW_ENCODE_OPEN)
  53. key_open = 1; /* enable open mode */
  54. return(0);
  55. }
  56. static int ioctl_get_encode(struct net_device *dev,
  57. struct iw_request_info *info,
  58. struct iw_point *erq,
  59. char *key)
  60. {
  61. int index = (erq->flags & IW_ENCODE_INDEX) - 1;
  62. /* Set the flags */
  63. erq->flags = 0;
  64. if(key_on == 0)
  65. erq->flags |= IW_ENCODE_DISABLED;
  66. if(key_open == 0)
  67. erq->flags |= IW_ENCODE_RESTRICTED;
  68. else
  69. erq->flags |= IW_ENCODE_OPEN;
  70. /* Which key do we want */
  71. if((index < 0) || (index >= MAX_KEYS))
  72. index = key_current;
  73. erq->flags |= index + 1;
  74. /* Copy the key to the user buffer */
  75. erq->length = key_size[index];
  76. memcpy(key, key_table[index], key_size[index]);
  77. return(0);
  78. }
  79. static int ioctl_get_range(struct net_device *dev,
  80. struct iw_request_info *info,
  81. struct iw_point *rrq,
  82. char *extra)
  83. {
  84. struct iw_range *range = (struct iw_range *) extra;
  85. rrq->length = sizeof(struct iw_range);
  86. memset(range, 0, sizeof(struct iw_range));
  87. #if WIRELESS_EXT > 10
  88. /* Version we are compiled with */
  89. range->we_version_compiled = WIRELESS_EXT;
  90. /* Minimum version we recommend */
  91. range->we_version_source = 8;
  92. #endif /* WIRELESS_EXT > 10 */
  93. #if WIRELESS_EXT > 8
  94. range->encoding_size[0] = 8; /* DES = 64 bits key */
  95. range->encoding_size[1] = 16;
  96. range->num_encoding_sizes = 2;
  97. range->max_encoding_tokens = 8;
  98. #endif /* WIRELESS_EXT > 8 */
  99. return(0);
  100. }
  101. /* --------------------------- BINDING --------------------------- */
  102. #if WIRELESS_EXT > 12
  103. static const iw_handler handler_table[] =
  104. {
  105. ...
  106. (iw_handler) ioctl_set_encode, /* SIOCSIWENCODE */
  107. (iw_handler) ioctl_get_encode, /* SIOCGIWENCODE */
  108. };
  109. #else /* WIRELESS_EXT < 12 */
  110. static int
  111. do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
  112. {
  113. struct iwreq *wrq = (struct iwreq *) ifr;
  114. int err = 0;
  115. switch (cmd)
  116. {
  117. #if WIRELESS_EXT > 8
  118. case SIOCSIWENCODE:
  119. {
  120. char keybuf[MAX_KEY_SIZE];
  121. if(wrq->u.encoding.pointer)
  122. {
  123. /* We actually have a key to set */
  124. if(wrq->u.encoding.length > MAX_KEY_SIZE)
  125. {
  126. err = -E2BIG;
  127. break;
  128. }
  129. if(copy_from_user(keybuf, wrq->u.encoding.pointer,
  130. wrq->u.encoding.length))
  131. {
  132. err = -EFAULT;
  133. break;
  134. }
  135. }
  136. else
  137. if(wrq->u.encoding.length != 0)
  138. {
  139. err = -EINVAL;
  140. break;
  141. }
  142. err = ioctl_set_encode(dev, NULL, &(wrq->u.encoding), keybuf);
  143. }
  144. break;
  145. case SIOCGIWENCODE:
  146. /* only super-user can see encryption key */
  147. if(! capable(CAP_NET_ADMIN))
  148. {
  149. err = -EPERM;
  150. break;
  151. }
  152. {
  153. char keybuf[MAX_KEY_SIZE];
  154. err = ioctl_get_encode(dev, NULL, &(wrq->u.encoding), keybuf);
  155. if(wrq->u.encoding.pointer)
  156. {
  157. if (copy_to_user(wrq->u.encoding.pointer, keybuf,
  158. wrq->u.encoding.length))
  159. err= -EFAULT;
  160. }
  161. }
  162. break;
  163. #endif /* WIRELESS_EXT > 8 */
  164. }
  165. return(err);
  166. }
  167. #endif /* WIRELESS_EXT < 12 */