irlan_filter.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. /*********************************************************************
  2. *
  3. * Filename: irlan_filter.c
  4. * Version:
  5. * Description:
  6. * Status: Experimental.
  7. * Author: Dag Brattli <dagb@cs.uit.no>
  8. * Created at: Fri Jan 29 11:16:38 1999
  9. * Modified at: Sat Oct 30 12:58:45 1999
  10. * Modified by: Dag Brattli <dagb@cs.uit.no>
  11. *
  12. * Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
  13. *
  14. * This program is free software; you can redistribute it and/or
  15. * modify it under the terms of the GNU General Public License as
  16. * published by the Free Software Foundation; either version 2 of
  17. * the License, or (at your option) any later version.
  18. *
  19. * Neither Dag Brattli nor University of Tromsø admit liability nor
  20. * provide warranty for any of this software. This material is
  21. * provided "AS-IS" and at no charge.
  22. *
  23. ********************************************************************/
  24. #include <linux/skbuff.h>
  25. #include <linux/random.h>
  26. #include <linux/seq_file.h>
  27. #include <net/irda/irlan_common.h>
  28. #include <net/irda/irlan_filter.h>
  29. /*
  30. * Function irlan_filter_request (self, skb)
  31. *
  32. * Handle filter request from client peer device
  33. *
  34. */
  35. void irlan_filter_request(struct irlan_cb *self, struct sk_buff *skb)
  36. {
  37. IRDA_ASSERT(self != NULL, return;);
  38. IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
  39. if ((self->provider.filter_type == IRLAN_DIRECTED) &&
  40. (self->provider.filter_operation == DYNAMIC))
  41. {
  42. pr_debug("Giving peer a dynamic Ethernet address\n");
  43. self->provider.mac_address[0] = 0x40;
  44. self->provider.mac_address[1] = 0x00;
  45. self->provider.mac_address[2] = 0x00;
  46. self->provider.mac_address[3] = 0x00;
  47. /* Use arbitration value to generate MAC address */
  48. if (self->provider.access_type == ACCESS_PEER) {
  49. self->provider.mac_address[4] =
  50. self->provider.send_arb_val & 0xff;
  51. self->provider.mac_address[5] =
  52. (self->provider.send_arb_val >> 8) & 0xff;
  53. } else {
  54. /* Just generate something for now */
  55. get_random_bytes(self->provider.mac_address+4, 1);
  56. get_random_bytes(self->provider.mac_address+5, 1);
  57. }
  58. skb->data[0] = 0x00; /* Success */
  59. skb->data[1] = 0x03;
  60. irlan_insert_string_param(skb, "FILTER_MODE", "NONE");
  61. irlan_insert_short_param(skb, "MAX_ENTRY", 0x0001);
  62. irlan_insert_array_param(skb, "FILTER_ENTRY",
  63. self->provider.mac_address, 6);
  64. return;
  65. }
  66. if ((self->provider.filter_type == IRLAN_DIRECTED) &&
  67. (self->provider.filter_mode == FILTER))
  68. {
  69. pr_debug("Directed filter on\n");
  70. skb->data[0] = 0x00; /* Success */
  71. skb->data[1] = 0x00;
  72. return;
  73. }
  74. if ((self->provider.filter_type == IRLAN_DIRECTED) &&
  75. (self->provider.filter_mode == NONE))
  76. {
  77. pr_debug("Directed filter off\n");
  78. skb->data[0] = 0x00; /* Success */
  79. skb->data[1] = 0x00;
  80. return;
  81. }
  82. if ((self->provider.filter_type == IRLAN_BROADCAST) &&
  83. (self->provider.filter_mode == FILTER))
  84. {
  85. pr_debug("Broadcast filter on\n");
  86. skb->data[0] = 0x00; /* Success */
  87. skb->data[1] = 0x00;
  88. return;
  89. }
  90. if ((self->provider.filter_type == IRLAN_BROADCAST) &&
  91. (self->provider.filter_mode == NONE))
  92. {
  93. pr_debug("Broadcast filter off\n");
  94. skb->data[0] = 0x00; /* Success */
  95. skb->data[1] = 0x00;
  96. return;
  97. }
  98. if ((self->provider.filter_type == IRLAN_MULTICAST) &&
  99. (self->provider.filter_mode == FILTER))
  100. {
  101. pr_debug("Multicast filter on\n");
  102. skb->data[0] = 0x00; /* Success */
  103. skb->data[1] = 0x00;
  104. return;
  105. }
  106. if ((self->provider.filter_type == IRLAN_MULTICAST) &&
  107. (self->provider.filter_mode == NONE))
  108. {
  109. pr_debug("Multicast filter off\n");
  110. skb->data[0] = 0x00; /* Success */
  111. skb->data[1] = 0x00;
  112. return;
  113. }
  114. if ((self->provider.filter_type == IRLAN_MULTICAST) &&
  115. (self->provider.filter_operation == GET))
  116. {
  117. pr_debug("Multicast filter get\n");
  118. skb->data[0] = 0x00; /* Success? */
  119. skb->data[1] = 0x02;
  120. irlan_insert_string_param(skb, "FILTER_MODE", "NONE");
  121. irlan_insert_short_param(skb, "MAX_ENTRY", 16);
  122. return;
  123. }
  124. skb->data[0] = 0x00; /* Command not supported */
  125. skb->data[1] = 0x00;
  126. pr_debug("Not implemented!\n");
  127. }
  128. /*
  129. * Function check_request_param (self, param, value)
  130. *
  131. * Check parameters in request from peer device
  132. *
  133. */
  134. void irlan_check_command_param(struct irlan_cb *self, char *param, char *value)
  135. {
  136. IRDA_ASSERT(self != NULL, return;);
  137. IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
  138. pr_debug("%s, %s\n", param, value);
  139. /*
  140. * This is experimental!! DB.
  141. */
  142. if (strcmp(param, "MODE") == 0) {
  143. self->use_udata = TRUE;
  144. return;
  145. }
  146. /*
  147. * FILTER_TYPE
  148. */
  149. if (strcmp(param, "FILTER_TYPE") == 0) {
  150. if (strcmp(value, "DIRECTED") == 0) {
  151. self->provider.filter_type = IRLAN_DIRECTED;
  152. return;
  153. }
  154. if (strcmp(value, "MULTICAST") == 0) {
  155. self->provider.filter_type = IRLAN_MULTICAST;
  156. return;
  157. }
  158. if (strcmp(value, "BROADCAST") == 0) {
  159. self->provider.filter_type = IRLAN_BROADCAST;
  160. return;
  161. }
  162. }
  163. /*
  164. * FILTER_MODE
  165. */
  166. if (strcmp(param, "FILTER_MODE") == 0) {
  167. if (strcmp(value, "ALL") == 0) {
  168. self->provider.filter_mode = ALL;
  169. return;
  170. }
  171. if (strcmp(value, "FILTER") == 0) {
  172. self->provider.filter_mode = FILTER;
  173. return;
  174. }
  175. if (strcmp(value, "NONE") == 0) {
  176. self->provider.filter_mode = FILTER;
  177. return;
  178. }
  179. }
  180. /*
  181. * FILTER_OPERATION
  182. */
  183. if (strcmp(param, "FILTER_OPERATION") == 0) {
  184. if (strcmp(value, "DYNAMIC") == 0) {
  185. self->provider.filter_operation = DYNAMIC;
  186. return;
  187. }
  188. if (strcmp(value, "GET") == 0) {
  189. self->provider.filter_operation = GET;
  190. return;
  191. }
  192. }
  193. }
  194. /*
  195. * Function irlan_print_filter (filter_type, buf)
  196. *
  197. * Print status of filter. Used by /proc file system
  198. *
  199. */
  200. #ifdef CONFIG_PROC_FS
  201. #define MASK2STR(m,s) { .mask = m, .str = s }
  202. void irlan_print_filter(struct seq_file *seq, int filter_type)
  203. {
  204. static struct {
  205. int mask;
  206. const char *str;
  207. } filter_mask2str[] = {
  208. MASK2STR(IRLAN_DIRECTED, "DIRECTED"),
  209. MASK2STR(IRLAN_FUNCTIONAL, "FUNCTIONAL"),
  210. MASK2STR(IRLAN_GROUP, "GROUP"),
  211. MASK2STR(IRLAN_MAC_FRAME, "MAC_FRAME"),
  212. MASK2STR(IRLAN_MULTICAST, "MULTICAST"),
  213. MASK2STR(IRLAN_BROADCAST, "BROADCAST"),
  214. MASK2STR(IRLAN_IPX_SOCKET, "IPX_SOCKET"),
  215. MASK2STR(0, NULL)
  216. }, *p;
  217. for (p = filter_mask2str; p->str; p++) {
  218. if (filter_type & p->mask)
  219. seq_printf(seq, "%s ", p->str);
  220. }
  221. seq_putc(seq, '\n');
  222. }
  223. #undef MASK2STR
  224. #endif