Commit | Line | Data |
---|---|---|
1da177e4 | 1 | /********************************************************************* |
6819bc2e | 2 | * |
1da177e4 | 3 | * Filename: irlan_filter.c |
6819bc2e YH |
4 | * Version: |
5 | * Description: | |
1da177e4 LT |
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> | |
6819bc2e | 11 | * |
1da177e4 | 12 | * Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved. |
6819bc2e YH |
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 | |
1da177e4 | 17 | * the License, or (at your option) any later version. |
6819bc2e | 18 | * |
db955170 | 19 | * Neither Dag Brattli nor University of Tromsø admit liability nor |
6819bc2e | 20 | * provide warranty for any of this software. This material is |
1da177e4 | 21 | * provided "AS-IS" and at no charge. |
6819bc2e | 22 | * |
1da177e4 LT |
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> | |
506e7beb | 30 | #include <net/irda/irlan_filter.h> |
1da177e4 LT |
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 | ||
6819bc2e | 43 | if ((self->provider.filter_type == IRLAN_DIRECTED) && |
1da177e4 LT |
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; | |
6819bc2e | 51 | |
1da177e4 LT |
52 | /* Use arbitration value to generate MAC address */ |
53 | if (self->provider.access_type == ACCESS_PEER) { | |
6819bc2e | 54 | self->provider.mac_address[4] = |
1da177e4 | 55 | self->provider.send_arb_val & 0xff; |
6819bc2e | 56 | self->provider.mac_address[5] = |
1da177e4 LT |
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); | |
6819bc2e | 68 | irlan_insert_array_param(skb, "FILTER_ENTRY", |
1da177e4 LT |
69 | self->provider.mac_address, 6); |
70 | return; | |
71 | } | |
6819bc2e YH |
72 | |
73 | if ((self->provider.filter_type == IRLAN_DIRECTED) && | |
1da177e4 LT |
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 | } | |
6819bc2e | 81 | if ((self->provider.filter_type == IRLAN_DIRECTED) && |
1da177e4 LT |
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 | ||
6819bc2e | 90 | if ((self->provider.filter_type == IRLAN_BROADCAST) && |
1da177e4 LT |
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 | } | |
6819bc2e | 98 | if ((self->provider.filter_type == IRLAN_BROADCAST) && |
1da177e4 LT |
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 | } | |
6819bc2e | 106 | if ((self->provider.filter_type == IRLAN_MULTICAST) && |
1da177e4 LT |
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 | } | |
6819bc2e | 114 | if ((self->provider.filter_type == IRLAN_MULTICAST) && |
1da177e4 LT |
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 | } | |
6819bc2e | 122 | if ((self->provider.filter_type == IRLAN_MULTICAST) && |
1da177e4 LT |
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 | __u8 *bytes; | |
147 | ||
148 | IRDA_DEBUG(4, "%s()\n", __FUNCTION__ ); | |
149 | ||
150 | bytes = value; | |
151 | ||
152 | IRDA_ASSERT(self != NULL, return;); | |
153 | IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;); | |
154 | ||
155 | IRDA_DEBUG(4, "%s, %s\n", param, value); | |
156 | ||
157 | /* | |
158 | * This is experimental!! DB. | |
159 | */ | |
160 | if (strcmp(param, "MODE") == 0) { | |
161 | IRDA_DEBUG(0, "%s()\n", __FUNCTION__ ); | |
162 | self->use_udata = TRUE; | |
163 | return; | |
164 | } | |
165 | ||
166 | /* | |
167 | * FILTER_TYPE | |
168 | */ | |
169 | if (strcmp(param, "FILTER_TYPE") == 0) { | |
170 | if (strcmp(value, "DIRECTED") == 0) { | |
171 | self->provider.filter_type = IRLAN_DIRECTED; | |
172 | return; | |
173 | } | |
174 | if (strcmp(value, "MULTICAST") == 0) { | |
175 | self->provider.filter_type = IRLAN_MULTICAST; | |
176 | return; | |
177 | } | |
178 | if (strcmp(value, "BROADCAST") == 0) { | |
179 | self->provider.filter_type = IRLAN_BROADCAST; | |
180 | return; | |
181 | } | |
182 | } | |
183 | /* | |
184 | * FILTER_MODE | |
185 | */ | |
186 | if (strcmp(param, "FILTER_MODE") == 0) { | |
187 | if (strcmp(value, "ALL") == 0) { | |
188 | self->provider.filter_mode = ALL; | |
189 | return; | |
190 | } | |
191 | if (strcmp(value, "FILTER") == 0) { | |
192 | self->provider.filter_mode = FILTER; | |
193 | return; | |
194 | } | |
195 | if (strcmp(value, "NONE") == 0) { | |
196 | self->provider.filter_mode = FILTER; | |
197 | return; | |
198 | } | |
199 | } | |
200 | /* | |
201 | * FILTER_OPERATION | |
202 | */ | |
203 | if (strcmp(param, "FILTER_OPERATION") == 0) { | |
204 | if (strcmp(value, "DYNAMIC") == 0) { | |
205 | self->provider.filter_operation = DYNAMIC; | |
206 | return; | |
207 | } | |
208 | if (strcmp(value, "GET") == 0) { | |
209 | self->provider.filter_operation = GET; | |
210 | return; | |
211 | } | |
212 | } | |
213 | } | |
214 | ||
215 | /* | |
216 | * Function irlan_print_filter (filter_type, buf) | |
217 | * | |
218 | * Print status of filter. Used by /proc file system | |
219 | * | |
220 | */ | |
221 | #ifdef CONFIG_PROC_FS | |
222 | #define MASK2STR(m,s) { .mask = m, .str = s } | |
223 | ||
224 | void irlan_print_filter(struct seq_file *seq, int filter_type) | |
225 | { | |
226 | static struct { | |
227 | int mask; | |
228 | const char *str; | |
229 | } filter_mask2str[] = { | |
230 | MASK2STR(IRLAN_DIRECTED, "DIRECTED"), | |
231 | MASK2STR(IRLAN_FUNCTIONAL, "FUNCTIONAL"), | |
232 | MASK2STR(IRLAN_GROUP, "GROUP"), | |
233 | MASK2STR(IRLAN_MAC_FRAME, "MAC_FRAME"), | |
234 | MASK2STR(IRLAN_MULTICAST, "MULTICAST"), | |
235 | MASK2STR(IRLAN_BROADCAST, "BROADCAST"), | |
236 | MASK2STR(IRLAN_IPX_SOCKET, "IPX_SOCKET"), | |
237 | MASK2STR(0, NULL) | |
238 | }, *p; | |
239 | ||
240 | for (p = filter_mask2str; p->str; p++) { | |
241 | if (filter_type & p->mask) | |
242 | seq_printf(seq, "%s ", p->str); | |
243 | } | |
244 | seq_putc(seq, '\n'); | |
245 | } | |
246 | #undef MASK2STR | |
247 | #endif |