Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

irlan_filter.c

Go to the documentation of this file.
00001 /*********************************************************************
00002  *                
00003  * Filename:      irlan_filter.c
00004  * Version:       
00005  * Description:   
00006  * Status:        Experimental.
00007  * Author:        Dag Brattli <dagb@cs.uit.no>
00008  * Created at:    Fri Jan 29 11:16:38 1999
00009  * Modified at:   Sat Oct 30 12:58:45 1999
00010  * Modified by:   Dag Brattli <dagb@cs.uit.no>
00011  * 
00012  *     Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
00013  *      
00014  *     This program is free software; you can redistribute it and/or 
00015  *     modify it under the terms of the GNU General Public License as 
00016  *     published by the Free Software Foundation; either version 2 of 
00017  *     the License, or (at your option) any later version.
00018  *  
00019  *     Neither Dag Brattli nor University of Tromsų admit liability nor
00020  *     provide warranty for any of this software. This material is 
00021  *     provided "AS-IS" and at no charge.
00022  *     
00023  ********************************************************************/
00024 
00025 #include <linux/skbuff.h>
00026 #include <linux/random.h>
00027 
00028 #include <net/irda/irlan_common.h>
00029 
00030 /*
00031  * Function handle_filter_request (self, skb)
00032  *
00033  *    Handle filter request from client peer device
00034  *
00035  */
00036 void handle_filter_request(struct irlan_cb *self, struct sk_buff *skb)
00037 {
00038         ASSERT(self != NULL, return;);
00039         ASSERT(self->magic == IRLAN_MAGIC, return;);
00040 
00041         if ((self->provider.filter_type == IRLAN_DIRECTED) && 
00042             (self->provider.filter_operation == DYNAMIC))
00043         {
00044                 IRDA_DEBUG(0, "Giving peer a dynamic Ethernet address\n");
00045                 self->provider.mac_address[0] = 0x40;
00046                 self->provider.mac_address[1] = 0x00;
00047                 self->provider.mac_address[2] = 0x00;
00048                 self->provider.mac_address[3] = 0x00;
00049                 
00050                 /* Use arbitration value to generate MAC address */
00051                 if (self->provider.access_type == ACCESS_PEER) {
00052                         self->provider.mac_address[4] = 
00053                                 self->provider.send_arb_val & 0xff;
00054                         self->provider.mac_address[5] = 
00055                                 (self->provider.send_arb_val >> 8) & 0xff;;
00056                 } else {
00057                         /* Just generate something for now */
00058                         get_random_bytes(self->provider.mac_address+4, 1);
00059                         get_random_bytes(self->provider.mac_address+5, 1);
00060                 }
00061 
00062                 skb->data[0] = 0x00; /* Success */
00063                 skb->data[1] = 0x03;
00064                 irlan_insert_string_param(skb, "FILTER_MODE", "NONE");
00065                 irlan_insert_short_param(skb, "MAX_ENTRY", 0x0001);
00066                 irlan_insert_array_param(skb, "FILTER_ENTRY", 
00067                                          self->provider.mac_address, 6);
00068                 return;
00069         }
00070         
00071         if ((self->provider.filter_type == IRLAN_DIRECTED) && 
00072             (self->provider.filter_mode == FILTER))
00073         {
00074                 IRDA_DEBUG(0, "Directed filter on\n");
00075                 skb->data[0] = 0x00; /* Success */
00076                 skb->data[1] = 0x00;
00077                 return;
00078         }
00079         if ((self->provider.filter_type == IRLAN_DIRECTED) && 
00080             (self->provider.filter_mode == NONE))
00081         {
00082                 IRDA_DEBUG(0, "Directed filter off\n");
00083                 skb->data[0] = 0x00; /* Success */
00084                 skb->data[1] = 0x00;
00085                 return;
00086         }
00087 
00088         if ((self->provider.filter_type == IRLAN_BROADCAST) && 
00089             (self->provider.filter_mode == FILTER))
00090         {
00091                 IRDA_DEBUG(0, "Broadcast filter on\n");
00092                 skb->data[0] = 0x00; /* Success */
00093                 skb->data[1] = 0x00;
00094                 return;
00095         }
00096         if ((self->provider.filter_type == IRLAN_BROADCAST) && 
00097             (self->provider.filter_mode == NONE))
00098         {
00099                 IRDA_DEBUG(0, "Broadcast filter off\n");
00100                 skb->data[0] = 0x00; /* Success */
00101                 skb->data[1] = 0x00;
00102                 return;
00103         }
00104         if ((self->provider.filter_type == IRLAN_MULTICAST) && 
00105             (self->provider.filter_mode == FILTER))
00106         {
00107                 IRDA_DEBUG(0, "Multicast filter on\n");
00108                 skb->data[0] = 0x00; /* Success */
00109                 skb->data[1] = 0x00;
00110                 return;
00111         }
00112         if ((self->provider.filter_type == IRLAN_MULTICAST) && 
00113             (self->provider.filter_mode == NONE))
00114         {
00115                 IRDA_DEBUG(0, "Multicast filter off\n");
00116                 skb->data[0] = 0x00; /* Success */
00117                 skb->data[1] = 0x00;
00118                 return;
00119         }
00120         if ((self->provider.filter_type == IRLAN_MULTICAST) && 
00121             (self->provider.filter_operation == GET))
00122         {
00123                 IRDA_DEBUG(0, "Multicast filter get\n");
00124                 skb->data[0] = 0x00; /* Success? */
00125                 skb->data[1] = 0x02;
00126                 irlan_insert_string_param(skb, "FILTER_MODE", "NONE");
00127                 irlan_insert_short_param(skb, "MAX_ENTRY", 16);
00128                 return;
00129         }
00130         skb->data[0] = 0x00; /* Command not supported */
00131         skb->data[1] = 0x00;
00132 
00133         IRDA_DEBUG(0, "Not implemented!\n");
00134 }
00135 
00136 /*
00137  * Function check_request_param (self, param, value)
00138  *
00139  *    Check parameters in request from peer device
00140  *
00141  */
00142 void irlan_check_command_param(struct irlan_cb *self, char *param, char *value)
00143 {
00144         __u8 *bytes;
00145 
00146         IRDA_DEBUG(4, __FUNCTION__ "()\n");
00147 
00148         bytes = value;
00149 
00150         ASSERT(self != NULL, return;);
00151         ASSERT(self->magic == IRLAN_MAGIC, return;);
00152 
00153         IRDA_DEBUG(4, "%s, %s\n", param, value);
00154 
00155         /*
00156          *  This is experimental!! DB.
00157          */
00158          if (strcmp(param, "MODE") == 0) {
00159                 IRDA_DEBUG(0, __FUNCTION__ "()\n");
00160                 self->use_udata = TRUE;
00161                 return;
00162         }
00163 
00164         /*
00165          *  FILTER_TYPE
00166          */
00167         if (strcmp(param, "FILTER_TYPE") == 0) {
00168                 if (strcmp(value, "DIRECTED") == 0) {
00169                         self->provider.filter_type = IRLAN_DIRECTED;
00170                         return;
00171                 }
00172                 if (strcmp(value, "MULTICAST") == 0) {
00173                         self->provider.filter_type = IRLAN_MULTICAST;
00174                         return;
00175                 }
00176                 if (strcmp(value, "BROADCAST") == 0) {
00177                         self->provider.filter_type = IRLAN_BROADCAST;
00178                         return;
00179                 }
00180         }
00181         /*
00182          *  FILTER_MODE
00183          */
00184         if (strcmp(param, "FILTER_MODE") == 0) {
00185                 if (strcmp(value, "ALL") == 0) {
00186                         self->provider.filter_mode = ALL;
00187                         return;
00188                 }
00189                 if (strcmp(value, "FILTER") == 0) {
00190                         self->provider.filter_mode = FILTER;
00191                         return;
00192                 }
00193                 if (strcmp(value, "NONE") == 0) {
00194                         self->provider.filter_mode = FILTER;
00195                         return;
00196                 }
00197         }
00198         /*
00199          *  FILTER_OPERATION
00200          */
00201         if (strcmp(param, "FILTER_OPERATION") == 0) {
00202                 if (strcmp(value, "DYNAMIC") == 0) {
00203                         self->provider.filter_operation = DYNAMIC;
00204                         return;
00205                 }
00206                 if (strcmp(value, "GET") == 0) {
00207                         self->provider.filter_operation = GET;
00208                         return;
00209                 }
00210         }
00211 }
00212 
00213 /*
00214  * Function irlan_print_filter (filter_type, buf)
00215  *
00216  *    Print status of filter. Used by /proc file system
00217  *
00218  */
00219 int irlan_print_filter(int filter_type, char *buf)
00220 {
00221         int len = 0;
00222 
00223         if (filter_type & IRLAN_DIRECTED)
00224                 len += sprintf(buf+len, "%s", "DIRECTED ");
00225         if (filter_type & IRLAN_FUNCTIONAL)
00226                 len += sprintf(buf+len, "%s", "FUNCTIONAL ");
00227         if (filter_type & IRLAN_GROUP)
00228                 len += sprintf(buf+len, "%s", "GROUP ");
00229         if (filter_type & IRLAN_MAC_FRAME)
00230                 len += sprintf(buf+len, "%s", "MAC_FRAME ");
00231         if (filter_type & IRLAN_MULTICAST)
00232                 len += sprintf(buf+len, "%s", "MULTICAST ");
00233         if (filter_type & IRLAN_BROADCAST)
00234                 len += sprintf(buf+len, "%s", "BROADCAST ");
00235         if (filter_type & IRLAN_IPX_SOCKET)
00236                 len += sprintf(buf+len, "%s", "IPX_SOCKET");
00237 
00238         len += sprintf(buf+len, "\n");
00239 
00240         return len;
00241 }