Main Page | Class List | File List | Class Members | File Members

wireless.c File Reference

#include <asm/uaccess.h>
#include <linux/config.h>
#include <linux/types.h>
#include <linux/netdevice.h>
#include <linux/rtnetlink.h>
#include <linux/if_arp.h>
#include <linux/wireless.h>
#include <net/iw_handler.h>

Go to the source code of this file.

Defines

#define WE_STRICT_WRITE
#define WE_EVENT_NETLINK
#define WE_SET_EVENT

Functions

iw_handler get_handler (struct net_device *dev, unsigned int cmd)
iw_statistics * get_wireless_stats (struct net_device *dev)
int call_commit_handler (struct net_device *dev)
int get_priv_size (__u16 args)
int dev_iwstats (struct net_device *dev, struct ifreq *ifr)
int ioctl_export_private (struct net_device *dev, struct ifreq *ifr)
int ioctl_standard_call (struct net_device *dev, struct ifreq *ifr, unsigned int cmd, iw_handler handler)
int ioctl_private_call (struct net_device *dev, struct ifreq *ifr, unsigned int cmd, iw_handler handler)
int wireless_process_ioctl (struct ifreq *ifr, unsigned int cmd)
int rtnetlink_fill_iwinfo (struct sk_buff *skb, struct net_device *dev, int type, char *event, int event_len)
void rtmsg_iwinfo (struct net_device *dev, char *event, int event_len)
void wireless_send_event (struct net_device *dev, unsigned int cmd, union iwreq_data *wrqu, char *extra)
int iw_handler_set_spy (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
int iw_handler_get_spy (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
int iw_handler_set_thrspy (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
int iw_handler_get_thrspy (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
void wireless_spy_update (struct net_device *dev, unsigned char *address, struct iw_quality *wstats)

Variables

const struct iw_ioctl_description standard_ioctl []
const int standard_ioctl_num
const struct iw_ioctl_description standard_event []
const int standard_event_num
const char priv_type_size []
const int event_type_size []


Define Documentation

#define WE_EVENT_NETLINK
 

Definition at line 77 of file wireless.c.

#define WE_SET_EVENT
 

Definition at line 78 of file wireless.c.

#define WE_STRICT_WRITE
 

Definition at line 68 of file wireless.c.


Function Documentation

int call_commit_handler struct net_device dev  )  [inline, static]
 

Definition at line 300 of file wireless.c.

References netif_running(), iw_handler_def::standard, and net_device::wireless_handlers.

Referenced by ioctl_private_call(), and ioctl_standard_call().

00301 { 00302 if((netif_running(dev)) && 00303 (dev->wireless_handlers->standard[0] != NULL)) { 00304 /* Call the commit handler on the driver */ 00305 return dev->wireless_handlers->standard[0](dev, NULL, 00306 NULL, NULL); 00307 } else 00308 return 0; /* Command completed successfully */ 00309 }

int dev_iwstats struct net_device dev,
struct ifreq *  ifr
[inline, static]
 

Definition at line 433 of file wireless.c.

References get_wireless_stats().

Referenced by wireless_process_ioctl().

00434 { 00435 /* Get stats from the driver */ 00436 struct iw_statistics *stats; 00437 00438 stats = get_wireless_stats(dev); 00439 if (stats != (struct iw_statistics *) NULL) { 00440 struct iwreq * wrq = (struct iwreq *)ifr; 00441 00442 /* Copy statistics to the user buffer */ 00443 if(copy_to_user(wrq->u.data.pointer, stats, 00444 sizeof(struct iw_statistics))) 00445 return -EFAULT; 00446 00447 /* Check if we need to clear the update flag */ 00448 if(wrq->u.data.flags != 0) 00449 stats->qual.updated = 0; 00450 return 0; 00451 } else 00452 return -EOPNOTSUPP; 00453 }

iw_handler get_handler struct net_device dev,
unsigned int  cmd
[inline, static]
 

Definition at line 243 of file wireless.c.

References iw_handler, iw_handler_def::num_private, iw_handler_def::num_standard, iw_handler_def::private, iw_handler_def::standard, and net_device::wireless_handlers.

Referenced by wireless_process_ioctl().

00245 { 00246 /* Don't "optimise" the following variable, it will crash */ 00247 unsigned int index; /* *MUST* be unsigned */ 00248 00249 /* Check if we have some wireless handlers defined */ 00250 if(dev->wireless_handlers == NULL) 00251 return NULL; 00252 00253 /* Try as a standard command */ 00254 index = cmd - SIOCIWFIRST; 00255 if(index < dev->wireless_handlers->num_standard) 00256 return dev->wireless_handlers->standard[index]; 00257 00258 /* Try as a private command */ 00259 index = cmd - SIOCIWFIRSTPRIV; 00260 if(index < dev->wireless_handlers->num_private) 00261 return dev->wireless_handlers->private[index]; 00262 00263 /* Not found */ 00264 return NULL; 00265 }

int get_priv_size __u16  args  )  [inline, static]
 

Definition at line 315 of file wireless.c.

References priv_type_size.

Referenced by ioctl_private_call().

00316 { 00317 int num = args & IW_PRIV_SIZE_MASK; 00318 int type = (args & IW_PRIV_TYPE_MASK) >> 12; 00319 00320 return num * priv_type_size[type]; 00321 }

struct iw_statistics* get_wireless_stats struct net_device dev  )  [inline, static]
 

Definition at line 271 of file wireless.c.

References net_device::get_wireless_stats.

Referenced by dev_iwstats().

00272 { 00273 return (dev->get_wireless_stats ? 00274 dev->get_wireless_stats(dev) : 00275 (struct iw_statistics *) NULL); 00276 /* In the future, get_wireless_stats may move from 'struct net_device' 00277 * to 'struct iw_handler_def', to de-bloat struct net_device. 00278 * Definitely worse a thought... */ 00279 }

int ioctl_export_private struct net_device dev,
struct ifreq *  ifr
[inline, static]
 

Definition at line 460 of file wireless.c.

References net_device::name, iw_handler_def::num_private_args, iw_handler_def::private_args, and net_device::wireless_handlers.

Referenced by wireless_process_ioctl().

00462 { 00463 struct iwreq * iwr = (struct iwreq *) ifr; 00464 00465 /* Check if the driver has something to export */ 00466 if((dev->wireless_handlers->num_private_args == 0) || 00467 (dev->wireless_handlers->private_args == NULL)) 00468 return -EOPNOTSUPP; 00469 00470 /* Check NULL pointer */ 00471 if(iwr->u.data.pointer == NULL) 00472 return -EFAULT; 00473 #ifdef WE_STRICT_WRITE 00474 /* Check if there is enough buffer up there */ 00475 if(iwr->u.data.length < dev->wireless_handlers->num_private_args) { 00476 printk(KERN_ERR "%s (WE) : Buffer for request SIOCGIWPRIV too small (%d<%d)\n", dev->name, iwr->u.data.length, dev->wireless_handlers->num_private_args); 00477 return -E2BIG; 00478 } 00479 #endif /* WE_STRICT_WRITE */ 00480 00481 /* Set the number of available ioctls. */ 00482 iwr->u.data.length = dev->wireless_handlers->num_private_args; 00483 00484 /* Copy structure to the user buffer. */ 00485 if (copy_to_user(iwr->u.data.pointer, 00486 dev->wireless_handlers->private_args, 00487 sizeof(struct iw_priv_args) * iwr->u.data.length)) 00488 return -EFAULT; 00489 00490 return 0; 00491 }

int ioctl_private_call struct net_device dev,
struct ifreq *  ifr,
unsigned int  cmd,
iw_handler  handler
[inline, static]
 

Definition at line 658 of file wireless.c.

References call_commit_handler(), iw_request_info::cmd, EIWCOMMIT, iw_request_info::flags, get_priv_size(), iw_handler, net_device::name, iw_handler_def::num_private_args, iw_handler_def::private_args, and net_device::wireless_handlers.

Referenced by wireless_process_ioctl().

00662 { 00663 struct iwreq * iwr = (struct iwreq *) ifr; 00664 struct iw_priv_args * descr = NULL; 00665 struct iw_request_info info; 00666 int extra_size = 0; 00667 int i; 00668 int ret = -EINVAL; 00669 00670 /* Get the description of the IOCTL */ 00671 for(i = 0; i < dev->wireless_handlers->num_private_args; i++) 00672 if(cmd == dev->wireless_handlers->private_args[i].cmd) { 00673 descr = &(dev->wireless_handlers->private_args[i]); 00674 break; 00675 } 00676 00677 #ifdef WE_IOCTL_DEBUG 00678 printk(KERN_DEBUG "%s (WE) : Found private handler for 0x%04X\n", 00679 ifr->ifr_name, cmd); 00680 if(descr) { 00681 printk(KERN_DEBUG "%s (WE) : Name %s, set %X, get %X\n", 00682 dev->name, descr->name, 00683 descr->set_args, descr->get_args); 00684 } 00685 #endif /* WE_IOCTL_DEBUG */ 00686 00687 /* Compute the size of the set/get arguments */ 00688 if(descr != NULL) { 00689 if(IW_IS_SET(cmd)) { 00690 int offset = 0; /* For sub-ioctls */ 00691 /* Check for sub-ioctl handler */ 00692 if(descr->name[0] == '\0') 00693 /* Reserve one int for sub-ioctl index */ 00694 offset = sizeof(__u32); 00695 00696 /* Size of set arguments */ 00697 extra_size = get_priv_size(descr->set_args); 00698 00699 /* Does it fits in iwr ? */ 00700 if((descr->set_args & IW_PRIV_SIZE_FIXED) && 00701 ((extra_size + offset) <= IFNAMSIZ)) 00702 extra_size = 0; 00703 } else { 00704 /* Size of set arguments */ 00705 extra_size = get_priv_size(descr->get_args); 00706 00707 /* Does it fits in iwr ? */ 00708 if((descr->get_args & IW_PRIV_SIZE_FIXED) && 00709 (extra_size <= IFNAMSIZ)) 00710 extra_size = 0; 00711 } 00712 } 00713 00714 /* Prepare the call */ 00715 info.cmd = cmd; 00716 info.flags = 0; 00717 00718 /* Check if we have a pointer to user space data or not. */ 00719 if(extra_size == 0) { 00720 /* No extra arguments. Trivial to handle */ 00721 ret = handler(dev, &info, &(iwr->u), (char *) &(iwr->u)); 00722 } else { 00723 char * extra; 00724 int err; 00725 00726 /* Check what user space is giving us */ 00727 if(IW_IS_SET(cmd)) { 00728 /* Check NULL pointer */ 00729 if((iwr->u.data.pointer == NULL) && 00730 (iwr->u.data.length != 0)) 00731 return -EFAULT; 00732 00733 /* Does it fits within bounds ? */ 00734 if(iwr->u.data.length > (descr->set_args & 00735 IW_PRIV_SIZE_MASK)) 00736 return -E2BIG; 00737 } else { 00738 /* Check NULL pointer */ 00739 if(iwr->u.data.pointer == NULL) 00740 return -EFAULT; 00741 } 00742 00743 #ifdef WE_IOCTL_DEBUG 00744 printk(KERN_DEBUG "%s (WE) : Malloc %d bytes\n", 00745 dev->name, extra_size); 00746 #endif /* WE_IOCTL_DEBUG */ 00747 00748 /* Always allocate for max space. Easier, and won't last 00749 * long... */ 00750 extra = kmalloc(extra_size, GFP_KERNEL); 00751 if (extra == NULL) { 00752 return -ENOMEM; 00753 } 00754 00755 /* If it is a SET, get all the extra data in here */ 00756 if(IW_IS_SET(cmd) && (iwr->u.data.length != 0)) { 00757 err = copy_from_user(extra, iwr->u.data.pointer, 00758 extra_size); 00759 if (err) { 00760 kfree(extra); 00761 return -EFAULT; 00762 } 00763 #ifdef WE_IOCTL_DEBUG 00764 printk(KERN_DEBUG "%s (WE) : Got %d elem\n", 00765 dev->name, iwr->u.data.length); 00766 #endif /* WE_IOCTL_DEBUG */ 00767 } 00768 00769 /* Call the handler */ 00770 ret = handler(dev, &info, &(iwr->u), extra); 00771 00772 /* If we have something to return to the user */ 00773 if (!ret && IW_IS_GET(cmd)) { 00774 err = copy_to_user(iwr->u.data.pointer, extra, 00775 extra_size); 00776 if (err) 00777 ret = -EFAULT; 00778 #ifdef WE_IOCTL_DEBUG 00779 printk(KERN_DEBUG "%s (WE) : Wrote %d elem\n", 00780 dev->name, iwr->u.data.length); 00781 #endif /* WE_IOCTL_DEBUG */ 00782 } 00783 00784 /* Cleanup - I told you it wasn't that long ;-) */ 00785 kfree(extra); 00786 } 00787 00788 00789 /* Call commit handler if needed and defined */ 00790 if(ret == -EIWCOMMIT) 00791 ret = call_commit_handler(dev); 00792 00793 return ret; 00794 }

int ioctl_standard_call struct net_device dev,
struct ifreq *  ifr,
unsigned int  cmd,
iw_handler  handler
[inline, static]
 

Definition at line 499 of file wireless.c.

References call_commit_handler(), iw_request_info::cmd, EIWCOMMIT, iw_request_info::flags, IW_DESCR_FLAG_EVENT, IW_DESCR_FLAG_RESTRICT, iw_handler, IW_HEADER_TYPE_POINT, net_device::name, standard_ioctl, standard_ioctl_num, and wireless_send_event().

Referenced by wireless_process_ioctl().

00503 { 00504 struct iwreq * iwr = (struct iwreq *) ifr; 00505 const struct iw_ioctl_description * descr; 00506 struct iw_request_info info; 00507 int ret = -EINVAL; 00508 int user_size = 0; 00509 00510 /* Get the description of the IOCTL */ 00511 if((cmd - SIOCIWFIRST) >= standard_ioctl_num) 00512 return -EOPNOTSUPP; 00513 descr = &(standard_ioctl[cmd - SIOCIWFIRST]); 00514 00515 #ifdef WE_IOCTL_DEBUG 00516 printk(KERN_DEBUG "%s (WE) : Found standard handler for 0x%04X\n", 00517 ifr->ifr_name, cmd); 00518 printk(KERN_DEBUG "%s (WE) : Header type : %d, Token type : %d, size : %d, token : %d\n", dev->name, descr->header_type, descr->token_type, descr->token_size, descr->max_tokens); 00519 #endif /* WE_IOCTL_DEBUG */ 00520 00521 /* Prepare the call */ 00522 info.cmd = cmd; 00523 info.flags = 0; 00524 00525 /* Check if we have a pointer to user space data or not */ 00526 if(descr->header_type != IW_HEADER_TYPE_POINT) { 00527 00528 /* No extra arguments. Trivial to handle */ 00529 ret = handler(dev, &info, &(iwr->u), NULL); 00530 00531 #ifdef WE_SET_EVENT 00532 /* Generate an event to notify listeners of the change */ 00533 if((descr->flags & IW_DESCR_FLAG_EVENT) && 00534 ((ret == 0) || (ret == -EIWCOMMIT))) 00535 wireless_send_event(dev, cmd, &(iwr->u), NULL); 00536 #endif /* WE_SET_EVENT */ 00537 } else { 00538 char * extra; 00539 int err; 00540 00541 /* Check what user space is giving us */ 00542 if(IW_IS_SET(cmd)) { 00543 /* Check NULL pointer */ 00544 if((iwr->u.data.pointer == NULL) && 00545 (iwr->u.data.length != 0)) 00546 return -EFAULT; 00547 /* Check if number of token fits within bounds */ 00548 if(iwr->u.data.length > descr->max_tokens) 00549 return -E2BIG; 00550 if(iwr->u.data.length < descr->min_tokens) 00551 return -EINVAL; 00552 } else { 00553 /* Check NULL pointer */ 00554 if(iwr->u.data.pointer == NULL) 00555 return -EFAULT; 00556 /* Save user space buffer size for checking */ 00557 user_size = iwr->u.data.length; 00558 } 00559 00560 #ifdef WE_IOCTL_DEBUG 00561 printk(KERN_DEBUG "%s (WE) : Malloc %d bytes\n", 00562 dev->name, descr->max_tokens * descr->token_size); 00563 #endif /* WE_IOCTL_DEBUG */ 00564 00565 /* Always allocate for max space. Easier, and won't last 00566 * long... */ 00567 extra = kmalloc(descr->max_tokens * descr->token_size, 00568 GFP_KERNEL); 00569 if (extra == NULL) { 00570 return -ENOMEM; 00571 } 00572 00573 /* If it is a SET, get all the extra data in here */ 00574 if(IW_IS_SET(cmd) && (iwr->u.data.length != 0)) { 00575 err = copy_from_user(extra, iwr->u.data.pointer, 00576 iwr->u.data.length * 00577 descr->token_size); 00578 if (err) { 00579 kfree(extra); 00580 return -EFAULT; 00581 } 00582 #ifdef WE_IOCTL_DEBUG 00583 printk(KERN_DEBUG "%s (WE) : Got %d bytes\n", 00584 dev->name, 00585 iwr->u.data.length * descr->token_size); 00586 #endif /* WE_IOCTL_DEBUG */ 00587 } 00588 00589 /* Call the handler */ 00590 ret = handler(dev, &info, &(iwr->u), extra); 00591 00592 /* If we have something to return to the user */ 00593 if (!ret && IW_IS_GET(cmd)) { 00594 #ifdef WE_STRICT_WRITE 00595 /* Check if there is enough buffer up there */ 00596 if(user_size < iwr->u.data.length) { 00597 printk(KERN_ERR "%s (WE) : Buffer for request %04X too small (%d<%d)\n", dev->name, cmd, user_size, iwr->u.data.length); 00598 kfree(extra); 00599 return -E2BIG; 00600 } 00601 #endif /* WE_STRICT_WRITE */ 00602 00603 err = copy_to_user(iwr->u.data.pointer, extra, 00604 iwr->u.data.length * 00605 descr->token_size); 00606 if (err) 00607 ret = -EFAULT; 00608 #ifdef WE_IOCTL_DEBUG 00609 printk(KERN_DEBUG "%s (WE) : Wrote %d bytes\n", 00610 dev->name, 00611 iwr->u.data.length * descr->token_size); 00612 #endif /* WE_IOCTL_DEBUG */ 00613 } 00614 00615 #ifdef WE_SET_EVENT 00616 /* Generate an event to notify listeners of the change */ 00617 if((descr->flags & IW_DESCR_FLAG_EVENT) && 00618 ((ret == 0) || (ret == -EIWCOMMIT))) { 00619 if(descr->flags & IW_DESCR_FLAG_RESTRICT) 00620 /* If the event is restricted, don't 00621 * export the payload */ 00622 wireless_send_event(dev, cmd, &(iwr->u), NULL); 00623 else 00624 wireless_send_event(dev, cmd, &(iwr->u), 00625 extra); 00626 } 00627 #endif /* WE_SET_EVENT */ 00628 00629 /* Cleanup - I told you it wasn't that long ;-) */ 00630 kfree(extra); 00631 } 00632 00633 /* Call commit handler if needed and defined */ 00634 if(ret == -EIWCOMMIT) 00635 ret = call_commit_handler(dev); 00636 00637 /* Here, we will generate the appropriate event if needed */ 00638 00639 return ret; 00640 }

int iw_handler_get_spy struct net_device dev,
struct iw_request_info info,
union iwreq_data *  wrqu,
char *  extra
 

Definition at line 1105 of file wireless.c.

References net_device::priv, iw_handler_def::spy_offset, and net_device::wireless_handlers.

01109 { 01110 #ifdef IW_WIRELESS_SPY 01111 struct iw_spy_data * spydata = (dev->priv + 01112 dev->wireless_handlers->spy_offset); 01113 struct sockaddr * address = (struct sockaddr *) extra; 01114 int i; 01115 01116 wrqu->data.length = spydata->spy_number; 01117 01118 /* Copy addresses. */ 01119 for(i = 0; i < spydata->spy_number; i++) { 01120 memcpy(address[i].sa_data, spydata->spy_address[i], ETH_ALEN); 01121 address[i].sa_family = AF_UNIX; 01122 } 01123 /* Copy stats to the user buffer (just after). */ 01124 if(spydata->spy_number > 0) 01125 memcpy(extra + (sizeof(struct sockaddr) *spydata->spy_number), 01126 spydata->spy_stat, 01127 sizeof(struct iw_quality) * spydata->spy_number); 01128 /* Reset updated flags. */ 01129 for(i = 0; i < spydata->spy_number; i++) 01130 spydata->spy_stat[i].updated = 0; 01131 return 0; 01132 #else /* IW_WIRELESS_SPY */ 01133 return -EOPNOTSUPP; 01134 #endif /* IW_WIRELESS_SPY */ 01135 }

int iw_handler_get_thrspy struct net_device dev,
struct iw_request_info info,
union iwreq_data *  wrqu,
char *  extra
 

Definition at line 1172 of file wireless.c.

References net_device::priv, iw_handler_def::spy_offset, and net_device::wireless_handlers.

01176 { 01177 #ifdef IW_WIRELESS_THRSPY 01178 struct iw_spy_data * spydata = (dev->priv + 01179 dev->wireless_handlers->spy_offset); 01180 struct iw_thrspy * threshold = (struct iw_thrspy *) extra; 01181 01182 /* Just do it */ 01183 memcpy(&(threshold->low), &(spydata->spy_thr_low), 01184 2 * sizeof(struct iw_quality)); 01185 01186 return 0; 01187 #else /* IW_WIRELESS_THRSPY */ 01188 return -EOPNOTSUPP; 01189 #endif /* IW_WIRELESS_THRSPY */ 01190 }

int iw_handler_set_spy struct net_device dev,
struct iw_request_info info,
union iwreq_data *  wrqu,
char *  extra
 

Definition at line 1052 of file wireless.c.

References net_device::priv, iw_handler_def::spy_offset, and net_device::wireless_handlers.

01056 { 01057 #ifdef IW_WIRELESS_SPY 01058 struct iw_spy_data * spydata = (dev->priv + 01059 dev->wireless_handlers->spy_offset); 01060 struct sockaddr * address = (struct sockaddr *) extra; 01061 01062 /* Disable spy collection while we copy the addresses. 01063 * As we don't disable interrupts, we need to do this to avoid races. 01064 * As we are the only writer, this is good enough. */ 01065 spydata->spy_number = 0; 01066 01067 /* Are there are addresses to copy? */ 01068 if(wrqu->data.length > 0) { 01069 int i; 01070 01071 /* Copy addresses */ 01072 for(i = 0; i < wrqu->data.length; i++) 01073 memcpy(spydata->spy_address[i], address[i].sa_data, 01074 ETH_ALEN); 01075 /* Reset stats */ 01076 memset(spydata->spy_stat, 0, 01077 sizeof(struct iw_quality) * IW_MAX_SPY); 01078 01079 #ifdef WE_SPY_DEBUG 01080 printk(KERN_DEBUG "iw_handler_set_spy() : offset %ld, spydata %p, num %d\n", dev->wireless_handlers->spy_offset, spydata, wrqu->data.length); 01081 for (i = 0; i < wrqu->data.length; i++) 01082 printk(KERN_DEBUG 01083 "%02X:%02X:%02X:%02X:%02X:%02X \n", 01084 spydata->spy_address[i][0], 01085 spydata->spy_address[i][1], 01086 spydata->spy_address[i][2], 01087 spydata->spy_address[i][3], 01088 spydata->spy_address[i][4], 01089 spydata->spy_address[i][5]); 01090 #endif /* WE_SPY_DEBUG */ 01091 } 01092 /* Enable addresses */ 01093 spydata->spy_number = wrqu->data.length; 01094 01095 return 0; 01096 #else /* IW_WIRELESS_SPY */ 01097 return -EOPNOTSUPP; 01098 #endif /* IW_WIRELESS_SPY */ 01099 }

int iw_handler_set_thrspy struct net_device dev,
struct iw_request_info info,
union iwreq_data *  wrqu,
char *  extra
 

Definition at line 1141 of file wireless.c.

References net_device::priv, iw_handler_def::spy_offset, and net_device::wireless_handlers.

01145 { 01146 #ifdef IW_WIRELESS_THRSPY 01147 struct iw_spy_data * spydata = (dev->priv + 01148 dev->wireless_handlers->spy_offset); 01149 struct iw_thrspy * threshold = (struct iw_thrspy *) extra; 01150 01151 /* Just do it */ 01152 memcpy(&(spydata->spy_thr_low), &(threshold->low), 01153 2 * sizeof(struct iw_quality)); 01154 01155 /* Clear flag */ 01156 memset(spydata->spy_thr_under, '\0', sizeof(spydata->spy_thr_under)); 01157 01158 #ifdef WE_SPY_DEBUG 01159 printk(KERN_DEBUG "iw_handler_set_thrspy() : low %d ; high %d\n", spydata->spy_thr_low.level, spydata->spy_thr_high.level); 01160 #endif /* WE_SPY_DEBUG */ 01161 01162 return 0; 01163 #else /* IW_WIRELESS_THRSPY */ 01164 return -EOPNOTSUPP; 01165 #endif /* IW_WIRELESS_THRSPY */ 01166 }

void rtmsg_iwinfo struct net_device dev,
char *  event,
int  event_len
[inline, static]
 

Definition at line 916 of file wireless.c.

References alloc_skb(), kfree_skb(), netlink_broadcast(), NETLINK_CB, NLMSG_GOODSIZE, rtnetlink_fill_iwinfo(), and rtnl.

Referenced by wireless_send_event().

00919 { 00920 struct sk_buff *skb; 00921 int size = NLMSG_GOODSIZE; 00922 00923 skb = alloc_skb(size, GFP_ATOMIC); 00924 if (!skb) 00925 return; 00926 00927 if (rtnetlink_fill_iwinfo(skb, dev, RTM_NEWLINK, 00928 event, event_len) < 0) { 00929 kfree_skb(skb); 00930 return; 00931 } 00932 NETLINK_CB(skb).dst_groups = RTMGRP_LINK; 00933 netlink_broadcast(rtnl, skb, 0, RTMGRP_LINK, GFP_ATOMIC); 00934 }

int rtnetlink_fill_iwinfo struct sk_buff skb,
struct net_device dev,
int  type,
char *  event,
int  event_len
[inline, static]
 

Definition at line 878 of file wireless.c.

References sk_buff::data, net_device::flags, net_device::ifindex, sk_buff::len, NLMSG_DATA, NLMSG_PUT, skb_trim(), sk_buff::tail, and net_device::type.

Referenced by rtmsg_iwinfo().

00883 { 00884 struct ifinfomsg *r; 00885 struct nlmsghdr *nlh; 00886 unsigned char *b = skb->tail; 00887 00888 nlh = NLMSG_PUT(skb, 0, 0, type, sizeof(*r)); 00889 r = NLMSG_DATA(nlh); 00890 r->ifi_family = AF_UNSPEC; 00891 r->ifi_type = dev->type; 00892 r->ifi_index = dev->ifindex; 00893 r->ifi_flags = dev->flags; 00894 r->ifi_change = 0; /* Wireless changes don't affect those flags */ 00895 00896 /* Add the wireless events in the netlink packet */ 00897 RTA_PUT(skb, IFLA_WIRELESS, 00898 event_len, event); 00899 00900 nlh->nlmsg_len = skb->tail - b; 00901 return skb->len; 00902 00903 nlmsg_failure: 00904 rtattr_failure: 00905 skb_trim(skb, b - skb->data); 00906 return -1; 00907 }

int wireless_process_ioctl struct ifreq *  ifr,
unsigned int  cmd
 

Definition at line 802 of file wireless.c.

References __dev_get_by_name(), dev_iwstats(), get_handler(), ioctl_export_private(), ioctl_private_call(), ioctl_standard_call(), iw_handler, and netif_device_present().

Referenced by dev_ioctl().

00803 { 00804 struct net_device *dev; 00805 iw_handler handler; 00806 00807 /* Permissions are already checked in dev_ioctl() before calling us. 00808 * The copy_to/from_user() of ifr is also dealt with in there */ 00809 00810 /* Make sure the device exist */ 00811 if ((dev = __dev_get_by_name(ifr->ifr_name)) == NULL) 00812 return -ENODEV; 00813 00814 /* A bunch of special cases, then the generic case... 00815 * Note that 'cmd' is already filtered in dev_ioctl() with 00816 * (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) */ 00817 switch(cmd) 00818 { 00819 case SIOCGIWSTATS: 00820 /* Get Wireless Stats */ 00821 return dev_iwstats(dev, ifr); 00822 00823 case SIOCGIWPRIV: 00824 /* Check if we have some wireless handlers defined */ 00825 if(dev->wireless_handlers != NULL) { 00826 /* We export to user space the definition of 00827 * the private handler ourselves */ 00828 return ioctl_export_private(dev, ifr); 00829 } 00830 // ## Fall-through for old API ## 00831 default: 00832 /* Generic IOCTL */ 00833 /* Basic check */ 00834 if (!netif_device_present(dev)) 00835 return -ENODEV; 00836 /* New driver API : try to find the handler */ 00837 handler = get_handler(dev, cmd); 00838 if(handler != NULL) { 00839 /* Standard and private are not the same */ 00840 if(cmd < SIOCIWFIRSTPRIV) 00841 return ioctl_standard_call(dev, 00842 ifr, 00843 cmd, 00844 handler); 00845 else 00846 return ioctl_private_call(dev, 00847 ifr, 00848 cmd, 00849 handler); 00850 } 00851 /* Old driver API : call driver ioctl handler */ 00852 if (dev->do_ioctl) { 00853 return dev->do_ioctl(dev, ifr, cmd); 00854 } 00855 return -EOPNOTSUPP; 00856 } 00857 /* Not reached */ 00858 return -EINVAL; 00859 }

void wireless_send_event struct net_device dev,
unsigned int  cmd,
union iwreq_data *  wrqu,
char *  extra
 

Definition at line 943 of file wireless.c.

References event_type_size, IW_HEADER_TYPE_POINT, net_device::name, rtmsg_iwinfo(), standard_event, standard_event_num, standard_ioctl, and standard_ioctl_num.

Referenced by ioctl_standard_call().

00947 { 00948 const struct iw_ioctl_description * descr = NULL; 00949 int extra_len = 0; 00950 struct iw_event *event; /* Mallocated whole event */ 00951 int event_len; /* Its size */ 00952 int hdr_len; /* Size of the event header */ 00953 /* Don't "optimise" the following variable, it will crash */ 00954 unsigned cmd_index; /* *MUST* be unsigned */ 00955 00956 /* Get the description of the IOCTL */ 00957 if(cmd <= SIOCIWLAST) { 00958 cmd_index = cmd - SIOCIWFIRST; 00959 if(cmd_index < standard_ioctl_num) 00960 descr = &(standard_ioctl[cmd_index]); 00961 } else { 00962 cmd_index = cmd - IWEVFIRST; 00963 if(cmd_index < standard_event_num) 00964 descr = &(standard_event[cmd_index]); 00965 } 00966 /* Don't accept unknown events */ 00967 if(descr == NULL) { 00968 /* Note : we don't return an error to the driver, because 00969 * the driver would not know what to do about it. It can't 00970 * return an error to the user, because the event is not 00971 * initiated by a user request. 00972 * The best the driver could do is to log an error message. 00973 * We will do it ourselves instead... 00974 */ 00975 printk(KERN_ERR "%s (WE) : Invalid/Unknown Wireless Event (0x%04X)\n", 00976 dev->name, cmd); 00977 return; 00978 } 00979 #ifdef WE_EVENT_DEBUG 00980 printk(KERN_DEBUG "%s (WE) : Got event 0x%04X\n", 00981 dev->name, cmd); 00982 printk(KERN_DEBUG "%s (WE) : Header type : %d, Token type : %d, size : %d, token : %d\n", dev->name, descr->header_type, descr->token_type, descr->token_size, descr->max_tokens); 00983 #endif /* WE_EVENT_DEBUG */ 00984 00985 /* Check extra parameters and set extra_len */ 00986 if(descr->header_type == IW_HEADER_TYPE_POINT) { 00987 /* Check if number of token fits within bounds */ 00988 if(wrqu->data.length > descr->max_tokens) { 00989 printk(KERN_ERR "%s (WE) : Wireless Event too big (%d)\n", dev->name, wrqu->data.length); 00990 return; 00991 } 00992 if(wrqu->data.length < descr->min_tokens) { 00993 printk(KERN_ERR "%s (WE) : Wireless Event too small (%d)\n", dev->name, wrqu->data.length); 00994 return; 00995 } 00996 /* Calculate extra_len - extra is NULL for restricted events */ 00997 if(extra != NULL) 00998 extra_len = wrqu->data.length * descr->token_size; 00999 #ifdef WE_EVENT_DEBUG 01000 printk(KERN_DEBUG "%s (WE) : Event 0x%04X, tokens %d, extra_len %d\n", dev->name, cmd, wrqu->data.length, extra_len); 01001 #endif /* WE_EVENT_DEBUG */ 01002 } 01003 01004 /* Total length of the event */ 01005 hdr_len = event_type_size[descr->header_type]; 01006 event_len = hdr_len + extra_len; 01007 01008 #ifdef WE_EVENT_DEBUG 01009 printk(KERN_DEBUG "%s (WE) : Event 0x%04X, hdr_len %d, event_len %d\n", dev->name, cmd, hdr_len, event_len); 01010 #endif /* WE_EVENT_DEBUG */ 01011 01012 /* Create temporary buffer to hold the event */ 01013 event = kmalloc(event_len, GFP_ATOMIC); 01014 if(event == NULL) 01015 return; 01016 01017 /* Fill event */ 01018 event->len = event_len; 01019 event->cmd = cmd; 01020 memcpy(&event->u, wrqu, hdr_len - IW_EV_LCP_LEN); 01021 if(extra != NULL) 01022 memcpy(((char *) event) + hdr_len, extra, extra_len); 01023 01024 #ifdef WE_EVENT_NETLINK 01025 /* rtnetlink event channel */ 01026 rtmsg_iwinfo(dev, (char *) event, event_len); 01027 #endif /* WE_EVENT_NETLINK */ 01028 01029 /* Cleanup */ 01030 kfree(event); 01031 01032 return; /* Always success, I guess ;-) */ 01033 }

void wireless_spy_update struct net_device dev,
unsigned char *  address,
struct iw_quality *  wstats
 

Definition at line 1239 of file wireless.c.

References net_device::priv, iw_spy_data::spy_address, iw_spy_data::spy_number, iw_handler_def::spy_offset, iw_spy_data::spy_stat, iw_spy_data::spy_thr_high, iw_spy_data::spy_thr_low, iw_spy_data::spy_thr_under, and net_device::wireless_handlers.

01242 { 01243 #ifdef IW_WIRELESS_SPY 01244 struct iw_spy_data * spydata = (dev->priv + 01245 dev->wireless_handlers->spy_offset); 01246 int i; 01247 int match = -1; 01248 01249 #ifdef WE_SPY_DEBUG 01250 printk(KERN_DEBUG "wireless_spy_update() : offset %ld, spydata %p, address %02X:%02X:%02X:%02X:%02X:%02X\n", dev->wireless_handlers->spy_offset, spydata, address[0], address[1], address[2], address[3], address[4], address[5]); 01251 #endif /* WE_SPY_DEBUG */ 01252 01253 /* Update all records that match */ 01254 for(i = 0; i < spydata->spy_number; i++) 01255 if(!memcmp(address, spydata->spy_address[i], ETH_ALEN)) { 01256 memcpy(&(spydata->spy_stat[i]), wstats, 01257 sizeof(struct iw_quality)); 01258 match = i; 01259 } 01260 #ifdef IW_WIRELESS_THRSPY 01261 /* Generate an event if we cross the spy threshold. 01262 * To avoid event storms, we have a simple hysteresis : we generate 01263 * event only when we go under the low threshold or above the 01264 * high threshold. */ 01265 if(match >= 0) { 01266 if(spydata->spy_thr_under[match]) { 01267 if(wstats->level > spydata->spy_thr_high.level) { 01268 spydata->spy_thr_under[match] = 0; 01269 iw_send_thrspy_event(dev, spydata, 01270 address, wstats); 01271 } 01272 } else { 01273 if(wstats->level < spydata->spy_thr_low.level) { 01274 spydata->spy_thr_under[match] = 1; 01275 iw_send_thrspy_event(dev, spydata, 01276 address, wstats); 01277 } 01278 } 01279 } 01280 #endif /* IW_WIRELESS_THRSPY */ 01281 #endif /* IW_WIRELESS_SPY */ 01282 }


Variable Documentation

const int event_type_size[] [static]
 

Initial value:

{ IW_EV_LCP_LEN, 0, IW_EV_CHAR_LEN, 0, IW_EV_UINT_LEN, IW_EV_FREQ_LEN, IW_EV_ADDR_LEN, 0, IW_EV_POINT_LEN, IW_EV_PARAM_LEN, IW_EV_QUAL_LEN, }
Definition at line 218 of file wireless.c.

Referenced by wireless_send_event().

const char priv_type_size[] [static]
 

Initial value:

{ 0, 1, 1, 0, sizeof(__u32), sizeof(struct iw_freq), sizeof(struct sockaddr), 0, }
Definition at line 206 of file wireless.c.

Referenced by get_priv_size().

const struct iw_ioctl_description standard_event[] [static]
 

Initial value:

{ { IW_HEADER_TYPE_ADDR, 0, 0, 0, 0, 0}, { IW_HEADER_TYPE_QUAL, 0, 0, 0, 0, 0}, { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_CUSTOM_MAX, 0}, { IW_HEADER_TYPE_ADDR, 0, 0, 0, 0, 0}, { IW_HEADER_TYPE_ADDR, 0, 0, 0, 0, 0}, }
Definition at line 190 of file wireless.c.

Referenced by wireless_send_event().

const int standard_event_num [static]
 

Initial value:

(sizeof(standard_event) / sizeof(struct iw_ioctl_description))
Definition at line 202 of file wireless.c.

Referenced by wireless_send_event().

const struct iw_ioctl_description standard_ioctl[] [static]
 

Definition at line 89 of file wireless.c.

Referenced by ioctl_standard_call(), and wireless_send_event().

const int standard_ioctl_num [static]
 

Initial value:

(sizeof(standard_ioctl) / sizeof(struct iw_ioctl_description))
Definition at line 183 of file wireless.c.

Referenced by ioctl_standard_call(), and wireless_send_event().


Generated on Wed Dec 1 21:25:41 2004 for Linux 2.4.23 Networking by doxygen 1.3.8