drm: fix DRM_IOCTL_MODE_GETFB handle-leak
[pandora-kernel.git] / net / irda / irlan / irlan_filter.c
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
25 #include <linux/skbuff.h>
26 #include <linux/random.h>
27 #include <linux/seq_file.h>
28
29 #include <net/irda/irlan_common.h>
30 #include <net/irda/irlan_filter.h>
31
32 /*
33  * Function irlan_filter_request (self, skb)
34  *
35  *    Handle filter request from client peer device
36  *
37  */
38 void irlan_filter_request(struct irlan_cb *self, struct sk_buff *skb)
39 {
40         IRDA_ASSERT(self != NULL, return;);
41         IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
42
43         if ((self->provider.filter_type == IRLAN_DIRECTED) &&
44             (self->provider.filter_operation == DYNAMIC))
45         {
46                 IRDA_DEBUG(0, "Giving peer a dynamic Ethernet address\n");
47                 self->provider.mac_address[0] = 0x40;
48                 self->provider.mac_address[1] = 0x00;
49                 self->provider.mac_address[2] = 0x00;
50                 self->provider.mac_address[3] = 0x00;
51
52                 /* Use arbitration value to generate MAC address */
53                 if (self->provider.access_type == ACCESS_PEER) {
54                         self->provider.mac_address[4] =
55                                 self->provider.send_arb_val & 0xff;
56                         self->provider.mac_address[5] =
57                                 (self->provider.send_arb_val >> 8) & 0xff;
58                 } else {
59                         /* Just generate something for now */
60                         get_random_bytes(self->provider.mac_address+4, 1);
61                         get_random_bytes(self->provider.mac_address+5, 1);
62                 }
63
64                 skb->data[0] = 0x00; /* Success */
65                 skb->data[1] = 0x03;
66                 irlan_insert_string_param(skb, "FILTER_MODE", "NONE");
67                 irlan_insert_short_param(skb, "MAX_ENTRY", 0x0001);
68                 irlan_insert_array_param(skb, "FILTER_ENTRY",
69                                          self->provider.mac_address, 6);
70                 return;
71         }
72
73         if ((self->provider.filter_type == IRLAN_DIRECTED) &&
74             (self->provider.filter_mode == FILTER))
75         {
76                 IRDA_DEBUG(0, "Directed filter on\n");
77                 skb->data[0] = 0x00; /* Success */
78                 skb->data[1] = 0x00;
79                 return;
80         }
81         if ((self->provider.filter_type == IRLAN_DIRECTED) &&
82             (self->provider.filter_mode == NONE))
83         {
84                 IRDA_DEBUG(0, "Directed filter off\n");
85                 skb->data[0] = 0x00; /* Success */
86                 skb->data[1] = 0x00;
87                 return;
88         }
89
90         if ((self->provider.filter_type == IRLAN_BROADCAST) &&
91             (self->provider.filter_mode == FILTER))
92         {
93                 IRDA_DEBUG(0, "Broadcast filter on\n");
94                 skb->data[0] = 0x00; /* Success */
95                 skb->data[1] = 0x00;
96                 return;
97         }
98         if ((self->provider.filter_type == IRLAN_BROADCAST) &&
99             (self->provider.filter_mode == NONE))
100         {
101                 IRDA_DEBUG(0, "Broadcast filter off\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 == FILTER))
108         {
109                 IRDA_DEBUG(0, "Multicast filter on\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_mode == NONE))
116         {
117                 IRDA_DEBUG(0, "Multicast filter off\n");
118                 skb->data[0] = 0x00; /* Success */
119                 skb->data[1] = 0x00;
120                 return;
121         }
122         if ((self->provider.filter_type == IRLAN_MULTICAST) &&
123             (self->provider.filter_operation == GET))
124         {
125                 IRDA_DEBUG(0, "Multicast filter get\n");
126                 skb->data[0] = 0x00; /* Success? */
127                 skb->data[1] = 0x02;
128                 irlan_insert_string_param(skb, "FILTER_MODE", "NONE");
129                 irlan_insert_short_param(skb, "MAX_ENTRY", 16);
130                 return;
131         }
132         skb->data[0] = 0x00; /* Command not supported */
133         skb->data[1] = 0x00;
134
135         IRDA_DEBUG(0, "Not implemented!\n");
136 }
137
138 /*
139  * Function check_request_param (self, param, value)
140  *
141  *    Check parameters in request from peer device
142  *
143  */
144 void irlan_check_command_param(struct irlan_cb *self, char *param, char *value)
145 {
146         IRDA_DEBUG(4, "%s()\n", __func__ );
147
148         IRDA_ASSERT(self != NULL, return;);
149         IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
150
151         IRDA_DEBUG(4, "%s, %s\n", param, value);
152
153         /*
154          *  This is experimental!! DB.
155          */
156          if (strcmp(param, "MODE") == 0) {
157                 IRDA_DEBUG(0, "%s()\n", __func__ );
158                 self->use_udata = TRUE;
159                 return;
160         }
161
162         /*
163          *  FILTER_TYPE
164          */
165         if (strcmp(param, "FILTER_TYPE") == 0) {
166                 if (strcmp(value, "DIRECTED") == 0) {
167                         self->provider.filter_type = IRLAN_DIRECTED;
168                         return;
169                 }
170                 if (strcmp(value, "MULTICAST") == 0) {
171                         self->provider.filter_type = IRLAN_MULTICAST;
172                         return;
173                 }
174                 if (strcmp(value, "BROADCAST") == 0) {
175                         self->provider.filter_type = IRLAN_BROADCAST;
176                         return;
177                 }
178         }
179         /*
180          *  FILTER_MODE
181          */
182         if (strcmp(param, "FILTER_MODE") == 0) {
183                 if (strcmp(value, "ALL") == 0) {
184                         self->provider.filter_mode = ALL;
185                         return;
186                 }
187                 if (strcmp(value, "FILTER") == 0) {
188                         self->provider.filter_mode = FILTER;
189                         return;
190                 }
191                 if (strcmp(value, "NONE") == 0) {
192                         self->provider.filter_mode = FILTER;
193                         return;
194                 }
195         }
196         /*
197          *  FILTER_OPERATION
198          */
199         if (strcmp(param, "FILTER_OPERATION") == 0) {
200                 if (strcmp(value, "DYNAMIC") == 0) {
201                         self->provider.filter_operation = DYNAMIC;
202                         return;
203                 }
204                 if (strcmp(value, "GET") == 0) {
205                         self->provider.filter_operation = GET;
206                         return;
207                 }
208         }
209 }
210
211 /*
212  * Function irlan_print_filter (filter_type, buf)
213  *
214  *    Print status of filter. Used by /proc file system
215  *
216  */
217 #ifdef CONFIG_PROC_FS
218 #define MASK2STR(m,s)   { .mask = m, .str = s }
219
220 void irlan_print_filter(struct seq_file *seq, int filter_type)
221 {
222         static struct {
223                 int mask;
224                 const char *str;
225         } filter_mask2str[] = {
226                 MASK2STR(IRLAN_DIRECTED,        "DIRECTED"),
227                 MASK2STR(IRLAN_FUNCTIONAL,      "FUNCTIONAL"),
228                 MASK2STR(IRLAN_GROUP,           "GROUP"),
229                 MASK2STR(IRLAN_MAC_FRAME,       "MAC_FRAME"),
230                 MASK2STR(IRLAN_MULTICAST,       "MULTICAST"),
231                 MASK2STR(IRLAN_BROADCAST,       "BROADCAST"),
232                 MASK2STR(IRLAN_IPX_SOCKET,      "IPX_SOCKET"),
233                 MASK2STR(0,                     NULL)
234         }, *p;
235
236         for (p = filter_mask2str; p->str; p++) {
237                 if (filter_type & p->mask)
238                         seq_printf(seq, "%s ", p->str);
239         }
240         seq_putc(seq, '\n');
241 }
242 #undef MASK2STR
243 #endif