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