📄 p80211wext.c
字号:
int err = 0; DBFENTER; if (!wlan_wext_write) { err = (-EOPNOTSUPP); goto exit; } msg.msgcode = DIDmsg_dot11req_mibset; switch (rrq->value) { case 1 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel1; break; case 2 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel2; break; case 3 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel3; break; case 4 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel4; break; case 5 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel5; break; case 6 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel6; break; case 7 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel7; break; case 8 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel8; break; default: mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel8; break; } memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); result = p80211req_dorequest(wlandev, (UINT8*)&msg); if (result) { err = -EFAULT; goto exit; } exit: DBFEXIT; return err;}static int p80211wext_giwtxpow(netdevice_t *dev, struct iw_request_info *info, struct iw_param *rrq, char *extra){ wlandevice_t *wlandev = (wlandevice_t*)dev->priv; p80211item_uint32_t mibitem; p80211msg_dot11req_mibset_t msg; int result; int err = 0; DBFENTER; msg.msgcode = DIDmsg_dot11req_mibget; mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel; memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); result = p80211req_dorequest(wlandev, (UINT8*)&msg); if (result) { err = -EFAULT; goto exit; } memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem)); // XXX handle OFF by setting disabled = 1; rrq->flags = 0; // IW_TXPOW_DBM; rrq->disabled = 0; rrq->fixed = 0; rrq->value = mibitem.data; exit: DBFEXIT; return err;}#endif /* WIRELESS_EXT > 9 */static int p80211wext_siwspy(netdevice_t *dev, struct iw_request_info *info, struct iw_point *srq, char *extra){ wlandevice_t *wlandev = (wlandevice_t*)dev->priv; struct sockaddr address[IW_MAX_SPY]; int number = srq->length; int i; DBFENTER; /* Copy the data from the input buffer */ memcpy(address, extra, sizeof(struct sockaddr)*number); wlandev->spy_number = 0; if (number > 0) { /* extract the addresses */ for (i = 0; i < number; i++) { memcpy(wlandev->spy_address[i], address[i].sa_data, ETH_ALEN); } /* reset stats */ memset(wlandev->spy_stat, 0, sizeof(struct iw_quality) * IW_MAX_SPY); /* set number of addresses */ wlandev->spy_number = number; } DBFEXIT; return 0;}/* jkriegl: from orinoco, modified */static int p80211wext_giwspy(netdevice_t *dev, struct iw_request_info *info, struct iw_point *srq, char *extra){ wlandevice_t *wlandev = (wlandevice_t*)dev->priv; struct sockaddr address[IW_MAX_SPY]; struct iw_quality spy_stat[IW_MAX_SPY]; int number; int i; DBFENTER; number = wlandev->spy_number; if (number > 0) { /* populate address and spy struct's */ for (i = 0; i < number; i++) { memcpy(address[i].sa_data, wlandev->spy_address[i], ETH_ALEN); address[i].sa_family = AF_UNIX; memcpy(&spy_stat[i], &wlandev->spy_stat[i], sizeof(struct iw_quality)); } /* reset update flag */ for (i=0; i < number; i++) wlandev->spy_stat[i].updated = 0; } /* push stuff to user space */ srq->length = number; memcpy(extra, address, sizeof(struct sockaddr)*number); memcpy(extra+sizeof(struct sockaddr)*number, spy_stat, sizeof(struct iw_quality)*number); DBFEXIT; return 0;}int prism2_result2err (int prism2_result){ int err = 0; switch (prism2_result) { case P80211ENUM_resultcode_invalid_parameters: err = -EINVAL; break; case P80211ENUM_resultcode_implementation_failure: err = -EIO; break; case P80211ENUM_resultcode_not_supported: err = -EOPNOTSUPP; break; default: err = 0; break; } return err;}#if WIRELESS_EXT > 13static int p80211wext_siwscan(netdevice_t *dev, struct iw_request_info *info, struct iw_point *srq, char *extra){ wlandevice_t *wlandev = (wlandevice_t*)dev->priv; p80211msg_dot11req_scan_t msg; int result; int err = 0; int i = 0; DBFENTER; if (wlandev->macmode == WLAN_MACMODE_ESS_AP) { WLAN_LOG_ERROR("Can't scan in AP mode\n"); err = (-EOPNOTSUPP); goto exit; } memset(&msg, 0x00, sizeof(p80211msg_dot11req_scan_t)); msg.msgcode = DIDmsg_dot11req_scan; msg.bsstype.data = P80211ENUM_bsstype_any; memset(&(msg.bssid.data), 0xFF, sizeof (p80211item_pstr6_t)); msg.bssid.data.len = 6; msg.scantype.data = P80211ENUM_scantype_active; msg.probedelay.data = 0; for (i = 0; i < 14; i++) msg.channellist.data.data[i] = i; msg.channellist.data.len = 14; msg.maxchanneltime.data = 250; msg.minchanneltime.data = 200; result = p80211req_dorequest(wlandev, (UINT8*)&msg); if (result) err = prism2_result2err (msg.resultcode.data); exit: DBFEXIT; return err;}/* Helper to translate scan into Wireless Extensions scan results. * Inspired by the prism54 code, which was in turn inspired by the * airo driver code. */static char *wext_translate_bss(char *current_ev, char *end_buf, p80211msg_dot11req_scan_results_t *bss){ struct iw_event iwe; /* Temporary buffer */ /* The first entry must be the MAC address */ memcpy(iwe.u.ap_addr.sa_data, bss->bssid.data.data, WLAN_BSSID_LEN); iwe.u.ap_addr.sa_family = ARPHRD_ETHER; iwe.cmd = SIOCGIWAP; current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN); /* The following entries will be displayed in the same order we give them */ /* The ESSID. */ if (bss->ssid.data.len > 0) { char essid[IW_ESSID_MAX_SIZE + 1]; int size; size = wlan_min(IW_ESSID_MAX_SIZE, bss->ssid.data.len); memset(&essid, 0, sizeof (essid)); memcpy(&essid, bss->ssid.data.data, size); WLAN_LOG_DEBUG(1, " essid size = %d\n", size); iwe.u.data.length = size; iwe.u.data.flags = 1; iwe.cmd = SIOCGIWESSID; current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, &essid[0]); WLAN_LOG_DEBUG(1, " essid size OK.\n"); } switch (bss->bsstype.data) { case P80211ENUM_bsstype_infrastructure: iwe.u.mode = IW_MODE_MASTER; break; case P80211ENUM_bsstype_independent: iwe.u.mode = IW_MODE_ADHOC; break; default: iwe.u.mode = 0; break; } iwe.cmd = SIOCGIWMODE; if (iwe.u.mode) current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_UINT_LEN); /* Encryption capability */ if (bss->privacy.data == P80211ENUM_truth_true) iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; else iwe.u.data.flags = IW_ENCODE_DISABLED; iwe.u.data.length = 0; iwe.cmd = SIOCGIWENCODE; current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, NULL); /* Add frequency. (short) bss->channel is the frequency in MHz */ iwe.u.freq.m = bss->dschannel.data; iwe.u.freq.e = 0; iwe.cmd = SIOCGIWFREQ; current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN); /* Add quality statistics */ iwe.u.qual.level = bss->signal.data; iwe.u.qual.noise = bss->noise.data; /* do a simple SNR for quality */ iwe.u.qual.qual = bss->signal.data - bss->noise.data; iwe.cmd = IWEVQUAL; current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); return current_ev;}static int p80211wext_giwscan(netdevice_t *dev, struct iw_request_info *info, struct iw_point *srq, char *extra){ wlandevice_t *wlandev = (wlandevice_t*)dev->priv; p80211msg_dot11req_scan_results_t msg; int result = 0; int err = 0; int i = 0; int scan_good = 0; char *current_ev = extra; DBFENTER; /* Since wireless tools doesn't really have a way of passing how * many scan results results there were back here, keep grabbing them * until we fail. */ do { memset(&msg, 0, sizeof(msg)); msg.msgcode = DIDmsg_dot11req_scan_results; msg.bssindex.data = i; result = p80211req_dorequest(wlandev, (UINT8*)&msg); if ((result != 0) || (msg.resultcode.data != P80211ENUM_resultcode_success)) { break; } current_ev = wext_translate_bss(current_ev, extra + IW_SCAN_MAX_DATA, &msg); scan_good = 1; i++; } while (i < IW_MAX_AP); srq->length = (current_ev - extra); srq->flags = 0; /* todo */ if (result && !scan_good) err = prism2_result2err (msg.resultcode.data); DBFEXIT; return err;}#endif/*typedef int (*iw_handler)(netdevice_t *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);*/#if WIRELESS_EXT > 12static iw_handler p80211wext_handlers[] = { (iw_handler) p80211wext_siwcommit, /* SIOCSIWCOMMIT */ (iw_handler) p80211wext_giwname, /* SIOCGIWNAME */ (iw_handler) NULL, /* SIOCSIWNWID */ (iw_handler) NULL, /* SIOCGIWNWID */ (iw_handler) p80211wext_siwfreq, /* SIOCSIWFREQ */ (iw_handler) p80211wext_giwfreq, /* SIOCGIWFREQ */ (iw_handler) p80211wext_siwmode, /* SIOCSIWMODE */ (iw_handler) p80211wext_giwmode, /* SIOCGIWMODE */ (iw_handler) NULL, /* SIOCSIWSENS */ (iw_handler) NULL, /* SIOCGIWSENS */ (iw_handler) NULL, /* not used */ /* SIOCSIWRANGE */ (iw_handler) p80211wext_giwrange, /* SIOCGIWRANGE */ (iw_handler) NULL, /* not used */ /* SIOCSIWPRIV */ (iw_handler) NULL, /* kernel code */ /* SIOCGIWPRIV */ (iw_handler) NULL, /* not used */ /* SIOCSIWSTATS */ (iw_handler) NULL, /* kernel code */ /* SIOCGIWSTATS */ (iw_handler) p80211wext_siwspy, /* SIOCSIWSPY */ (iw_handler) p80211wext_giwspy, /* SIOCGIWSPY */ (iw_handler) NULL, /* -- hole -- */ (iw_handler) NULL, /* -- hole -- */ (iw_handler) NULL, /* SIOCSIWAP */ (iw_handler) p80211wext_giwap, /* SIOCGIWAP */ (iw_handler) NULL, /* -- hole -- */ (iw_handler) NULL, /* SIOCGIWAPLIST */#if WIRELESS_EXT > 13 (iw_handler) p80211wext_siwscan, /* SIOCSIWSCAN */ (iw_handler) p80211wext_giwscan, /* SIOCGIWSCAN */#else /* WIRELESS_EXT > 13 */ (iw_handler) NULL, /* null */ /* SIOCSIWSCAN */ (iw_handler) NULL, /* null */ /* SIOCGIWSCAN */#endif /* WIRELESS_EXT > 13 */ (iw_handler) p80211wext_siwessid, /* SIOCSIWESSID */ (iw_handler) p80211wext_giwessid, /* SIOCGIWESSID */ (iw_handler) NULL, /* SIOCSIWNICKN */ (iw_handler) p80211wext_giwessid, /* SIOCGIWNICKN */ (iw_handler) NULL, /* -- hole -- */ (iw_handler) NULL, /* -- hole -- */ (iw_handler) NULL, /* SIOCSIWRATE */ (iw_handler) p80211wext_giwrate, /* SIOCGIWRATE */ (iw_handler) p80211wext_siwrts, /* SIOCSIWRTS */ (iw_handler) p80211wext_giwrts, /* SIOCGIWRTS */ (iw_handler) p80211wext_siwfrag, /* SIOCSIWFRAG */ (iw_handler) p80211wext_giwfrag, /* SIOCGIWFRAG */ (iw_handler) p80211wext_siwtxpow, /* SIOCSIWTXPOW */ (iw_handler) p80211wext_giwtxpow, /* SIOCGIWTXPOW */ (iw_handler) p80211wext_siwretry, /* SIOCSIWRETRY */ (iw_handler) p80211wext_giwretry, /* SIOCGIWRETRY */ (iw_handler) p80211wext_siwencode, /* SIOCSIWENCODE */ (iw_handler) p80211wext_giwencode, /* SIOCGIWENCODE */ (iw_handler) NULL, /* SIOCSIWPOWER */ (iw_handler) NULL, /* SIOCGIWPOWER */};struct iw_handler_def p80211wext_handler_def = { .num_standard = sizeof(p80211wext_handlers) / sizeof(iw_handler), .num_private = 0, .num_private_args = 0, .standard = p80211wext_handlers, .private = NULL, .private_args = NULL,#if WIRELESS_EXT > 16 .get_wireless_stats = p80211wext_get_wireless_stats#endif};#endif/* wireless extensions' ioctls */ int p80211wext_support_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd){ wlandevice_t *wlandev = (wlandevice_t*)dev->priv;#if WIRELESS_EXT < 13 struct iwreq *iwr = (struct iwreq*)ifr;#endif p80211item_uint32_t mibitem; int err = 0; DBFENTER; mibitem.status = P80211ENUM_msgitem_status_data_ok; if ( wlandev->msdstate != WLAN_MSD_RUNNING ) { err = -ENODEV; goto exit; } WLAN_LOG_DEBUG(1, "Received wireless extension ioctl #%d.\n", cmd); switch (cmd) {#if WIRELESS_EXT < 13 case SIOCSIWNAME: /* unused */ err = (-EOPNOTSUPP); break; case SIOCGIWNAME: /* get name == wireless protocol */ err = p80211wext_giwname(dev, NULL, (char *) &iwr->u, NULL); break; case SIOCSIWNWID: case SIOCGIWNWID: err = (-EOPNOTSUPP); break; case SIOCSIWFREQ: /* set channel */ err = p80211wext_siwfreq(dev, NULL, &(iwr->u.freq), NULL); break; case SIOCGIWFREQ: /* get channel */ err = p80211wext_giwfreq(dev, NULL, &(iwr->u.freq), NULL); break; case SIOCSIWRANGE: case SIOCSIWPRIV: case SIOCSIWAP: /* set access point MAC addresses (BSSID) */ err = (-EOPNOTSUPP); break; case SIOCGIWAP: /* get access point MAC addresses (BSSID) */ err = p80211wext_giwap(dev, NULL, &(iwr->u.ap_addr), NULL); break;#if WIRELESS_EXT > 8 case SIOCSIWMODE: /* set operation mode */ case SIOCSIWESSID: /* set SSID (network name) */ case SIOCSIWRATE: /* set default bit rate (bps) */ err = (-EOPNOTSUPP); break; case SIOCGIWMODE: /* get operation mode */ err = p80211wext_giwmode(dev, NULL, &iwr->u.mode, NULL); break; case SIOCGIWNICKN: /* get node name/nickname */ case SIOCGIWESSID: /* get SSID */ if(iwr->u.essid.pointer) { char ssid[IW_ESSID_MAX_SIZE+1]; memset(ssid, 0, sizeof(ssid)); err = p80211wext_giwessid(dev, NULL, &iwr->u.essid, ssid); if(copy_to_user(iwr->u.essid.pointer, ssid, sizeof(ssid))) err = (-EFAULT); } break; case SIOCGIWRATE: err = p80211wext_giwrate(dev, NULL, &iwr->u.bitrate, NULL); break; case SIOCGIWRTS: err = p80211wext_giwrts(dev, NULL, &iwr->u.rts, NULL); break; case SIOCGIWFRAG: err = p80211wext_giwfrag(dev, NULL, &iwr->u.rts, NULL); break; case SIOCGIWENCODE: if (!capable(CAP_NET_ADMIN)) err = -EPERM; else if (iwr->u.encoding.pointer) { char keybuf[MAX_KEYLEN]; err = p80211wext_giwencode(dev, NULL, &iwr->u.encoding, keybuf); if (copy_to_user(iwr->u.encoding.pointer, keybuf, iwr->u.encoding.length)) err = -EFAULT; } break; case SIOCGIWAPLIST: case SIOCSIWRTS: case SIOCSIWFRAG: case SIOCSIWSENS: case SIOCGIWSENS: case SIOCSIWNICKN: /* set node name/nickname */ case SIOCSIWENCODE: /* set encoding token & mode */ case SIOCSIWSPY: case SIOCGIWSPY: case SIOCSIWPOWER: case SIOCGIWPOWER: case SIOCGIWPRIV: err = (-EOPNOTSUPP); break; case SIOCGIWRANGE: if(iwr->u.data.pointer != NULL) { struct iw_range range; err = p80211wext_giwrange(dev, NULL, &iwr->u.data, (char *) &range); /* Push that up to the caller */ if (copy_to_user(iwr->u.data.pointer, &range, sizeof(range))) err = -EFAULT; } break;#endif /* WIRELESS_EXT > 8 */#if WIRELESS_EXT > 9 case SIOCSIWTXPOW: err = (-EOPNOTSUPP); break; case SIOCGIWTXPOW: err = p80211wext_giwtxpow(dev, NULL, &iwr->u.txpower, NULL); break;#endif /* WIRELESS_EXT > 9 */ #if WIRELESS_EXT > 10 case SIOCSIWRETRY: err = (-EOPNOTSUPP); break; case SIOCGIWRETRY: err = p80211wext_giwretry(dev, NULL, &iwr->u.retry, NULL); break;#endif /* WIRELESS_EXT > 10 */ #endif /* WIRELESS_EXT <= 12 */ default: err = (-EOPNOTSUPP); break; } exit: DBFEXIT; return (err);}int p80211wext_event_associated(wlandevice_t *wlandev, int assoc){ union iwreq_data data; DBFENTER;#if WIRELESS_EXT > 13 /* Send the association state first */ data.ap_addr.sa_family = ARPHRD_ETHER; if (assoc) { memcpy(data.ap_addr.sa_data, wlandev->bssid, WLAN_ADDR_LEN); } else { memset(data.ap_addr.sa_data, 0, WLAN_ADDR_LEN); } if (wlan_wext_write) wireless_send_event(wlandev->netdev, SIOCGIWAP, &data, NULL); if (!assoc) goto done; // XXX send association data, like IEs, etc etc.#endif done: DBFEXIT; return 0;}#endif /* compatibility to wireless extensions */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -