📄 wrapper.c
字号:
memset(&iwe, 0, sizeof(iwe)); iwe.cmd = SIOCGIWAP; iwe.u.ap_addr.sa_family = ARPHRD_ETHER; iwe.len = IW_EV_ADDR_LEN; memcpy(iwe.u.ap_addr.sa_data, item->mac, ETH_ALEN); event = iwe_stream_add_event(event, end_buf, &iwe, IW_EV_ADDR_LEN); /* add essid */ memset(&iwe, 0, sizeof(iwe)); iwe.cmd = SIOCGIWESSID; iwe.u.data.length = item->ssid.length; if (iwe.u.data.length > IW_ESSID_MAX_SIZE) iwe.u.data.length = IW_ESSID_MAX_SIZE; iwe.u.data.flags = 1; iwe.len = IW_EV_POINT_LEN + iwe.u.data.length; event = iwe_stream_add_point(event, end_buf, &iwe, item->ssid.ssid); /* add protocol name */ memset(&iwe, 0, sizeof(iwe)); iwe.cmd = SIOCGIWNAME; strncpy(iwe.u.name, net_type_to_name(item->net_type), IFNAMSIZ); event = iwe_stream_add_event(event, end_buf, &iwe, IW_EV_CHAR_LEN); /* add mode */ memset(&iwe, 0, sizeof(iwe)); iwe.cmd = SIOCGIWMODE; if (item->mode == NDIS_MODE_ADHOC) iwe.u.mode = IW_MODE_ADHOC; else if (item->mode == NDIS_MODE_INFRA) iwe.u.mode = IW_MODE_INFRA; else // if (item->mode == NDIS_MODE_AUTO) iwe.u.mode = IW_MODE_AUTO; event = iwe_stream_add_event(event, end_buf, &iwe, IW_EV_UINT_LEN); /* add freq */ memset(&iwe, 0, sizeof(iwe)); iwe.cmd = SIOCGIWFREQ; iwe.u.freq.m = item->config.ds_config; if (item->config.ds_config > 1000000) { iwe.u.freq.m = item->config.ds_config / 10; iwe.u.freq.e = 1; } else iwe.u.freq.m = item->config.ds_config; /* convert from kHz to Hz */ iwe.u.freq.e += 3; iwe.len = IW_EV_FREQ_LEN; event = iwe_stream_add_event(event, end_buf, &iwe, IW_EV_FREQ_LEN); /* add qual */ memset(&iwe, 0, sizeof(iwe)); iwe.cmd = IWEVQUAL; iwe.u.qual.level = item->rssi; iwe.u.qual.noise = 0; iwe.u.qual.qual = 0; iwe.len = IW_EV_QUAL_LEN; event = iwe_stream_add_event(event, end_buf, &iwe, IW_EV_QUAL_LEN); /* add key info */ memset(&iwe, 0, sizeof(iwe)); iwe.cmd = SIOCGIWENCODE; if (item->privacy == NDIS_PRIV_ACCEPT_ALL) iwe.u.data.flags = IW_ENCODE_DISABLED; else iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; iwe.u.data.length = 0; iwe.len = IW_EV_POINT_LEN; event = iwe_stream_add_point(event, end_buf, &iwe, item->ssid.ssid); /* add rate */ memset(&iwe, 0, sizeof(iwe)); current_val = event + IW_EV_LCP_LEN; iwe.cmd = SIOCGIWRATE; for (i = 0 ; i < NDIS_MAX_RATES ; i++) { if (item->rates[i] == 0) break; iwe.u.bitrate.value = ((item->rates[i] & 0x7f) * 500000); current_val = iwe_stream_add_value(event, current_val, end_buf, &iwe, IW_EV_PARAM_LEN); } if ((current_val - event) > IW_EV_LCP_LEN) event = current_val; return event;}static int ndis_list_scan(struct ndis_handle *handle){ int res; res = set_int(handle, NDIS_OID_BSSID_LIST_SCAN, 0); if (res) printk(KERN_ERR "BSSID list scan failed with %d\n", res); return 0;}static int ndis_set_scan(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ /* all work is now done by timer func ndis_list_scan */ return 0;}static int ndis_get_scan(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ struct ndis_handle *handle = dev->priv; int i, res, written, needed; struct list_scan list_scan; char *event = extra; char *cur_item ; written = needed = 0; res = doquery(handle, NDIS_OID_BSSID_LIST, (char*)&list_scan, sizeof(list_scan), &written, &needed); if (needed > 0) printk(KERN_ERR "Not enough space for all APs available\n"); if (res) return -1; for (i = 0, cur_item = (char *)&(list_scan.items[0]) ; i < list_scan.num_items && i < MAX_SCAN_LIST_ITEMS ; i++) { char *prev_item = cur_item ; event = ndis_translate_scan(dev, event, extra + IW_SCAN_MAX_DATA, (struct ssid_item *)cur_item); cur_item += ((struct ssid_item *)prev_item)->length; } wrqu->data.length = event - extra; wrqu->data.flags = 0; return 0;}void add_scan_timer(unsigned long handle){ struct timer_list *timer_list = &(((struct ndis_handle *)handle)->driver->timer_list); ndis_list_scan((struct ndis_handle *)handle); timer_list->data = (unsigned long) handle; timer_list->function = &add_scan_timer; timer_list->expires = jiffies + 1000; add_timer(timer_list);}static int ndis_set_power_mode(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ struct ndis_handle *handle = dev->priv; int res, power_mode; if (wrqu->power.disabled == 1) power_mode = NDIS_POWER_OFF; else if (wrqu->power.flags & IW_POWER_MIN) power_mode = NDIS_POWER_MIN; else // if (wrqu->power.flags & IW_POWER_MAX) power_mode = NDIS_POWER_MAX; res = set_int(handle, NDIS_OID_POWER_MODE, power_mode); if (res) return -1; return 0;}static int ndis_get_power_mode(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra){ struct ndis_handle *handle = dev->priv; int res, power_mode; res = query_int(handle, NDIS_OID_POWER_MODE, &power_mode); if (res) return -1; if (power_mode == NDIS_POWER_OFF) wrqu->power.disabled = 1; else { wrqu->power.flags |= IW_POWER_ALL_R; wrqu->power.flags |= IW_POWER_TIMEOUT; wrqu->power.value = 0; if (power_mode == NDIS_POWER_MIN) wrqu->power.flags |= IW_POWER_MIN; else // if (power_mode == NDIS_POWER_MAX) wrqu->power.flags |= IW_POWER_MAX; } return 0;}static const iw_handler ndis_handler[] = { //[SIOCGIWSENS - SIOCIWFIRST] = ndis_get_sens, [SIOCGIWNAME - SIOCIWFIRST] = ndis_get_name, [SIOCSIWESSID - SIOCIWFIRST] = ndis_set_essid, [SIOCGIWESSID - SIOCIWFIRST] = ndis_get_essid, [SIOCSIWMODE - SIOCIWFIRST] = ndis_set_mode, [SIOCGIWMODE - SIOCIWFIRST] = ndis_get_mode, [SIOCGIWFREQ - SIOCIWFIRST] = ndis_get_freq, [SIOCGIWTXPOW - SIOCIWFIRST] = ndis_get_tx_power, [SIOCGIWRATE - SIOCIWFIRST] = ndis_get_bitrate, [SIOCGIWRTS - SIOCIWFIRST] = ndis_get_rts_threshold, [SIOCGIWFRAG - SIOCIWFIRST] = ndis_get_frag_threshold, //[SIOCSIWRETRY - SIOCIWFIRST] = ndis_get_rety_limit, [SIOCGIWAP - SIOCIWFIRST] = ndis_get_ap_address, [SIOCSIWENCODE - SIOCIWFIRST] = ndis_set_wep, [SIOCGIWENCODE - SIOCIWFIRST] = ndis_get_wep, [SIOCSIWSCAN - SIOCIWFIRST] = ndis_set_scan, [SIOCGIWSCAN - SIOCIWFIRST] = ndis_get_scan, [SIOCGIWPOWER - SIOCIWFIRST] = ndis_get_power_mode, [SIOCSIWPOWER - SIOCIWFIRST] = ndis_set_power_mode,};static const struct iw_handler_def ndis_handler_def = { .num_standard = sizeof(ndis_handler) / sizeof(iw_handler), .standard = (iw_handler *)ndis_handler,};static int call_init(struct ndis_handle *handle){ __u32 res, res2; __u32 selected_medium; __u32 mediumtypes[] = {0,1,2,3,4,5,6,7,8,9,10,11,12}; DBGTRACE("Calling init at %08x rva(%08x)\n", (int)handle->driver->miniport_char.init, (int)handle->driver->miniport_char.init - image_offset); res = handle->driver->miniport_char.init(&res2, &selected_medium, mediumtypes, 13, handle, handle); DBGTRACE("past init res: %08x\n\n", res); return res != 0;}static void call_halt(struct ndis_handle *handle){ DBGTRACE("Calling halt at %08x rva(%08x)\n", (int)handle->driver->miniport_char.halt, (int)handle->driver->miniport_char.halt - image_offset); handle->driver->miniport_char.halt(handle->adapter_ctx);}static unsigned int call_entry(struct ndis_driver *driver){ int res; char regpath[] = {'a', 0, 'b', 0, 0, 0}; DBGTRACE("Calling entry at %08x rva(%08x)\n", (int)driver->entry, (int)driver->entry - image_offset); res = driver->entry((void*)driver, regpath); DBGTRACE("Past entry: Version: %d.%d\n\n\n", driver->miniport_char.majorVersion, driver->miniport_char.minorVersion); /* Dump addresses of driver suppoled callbacks */#ifdef DEBUG { int i; int *adr = (int*) &driver->miniport_char.CheckForHangTimer; char *name[] = { "CheckForHangTimer", "DisableInterruptHandler", "EnableInterruptHandler", "halt", "HandleInterruptHandler", "init", "ISRHandler", "query", "ReconfigureHandler", "ResetHandler", "SendHandler", "SetInformationHandler", "TransferDataHandler", "ReturnPacketHandler", "SendPacketsHandler", "AllocateCompleteHandler",/* "CoCreateVcHandler", "CoDeleteVcHandler", "CoActivateVcHandler", "CoDeactivateVcHandler", "CoSendPacketsHandler", "CoRequestHandler"*/ }; for(i = 0; i < 16; i++) { DBGTRACE("%08x (rva %08x):%s\n", adr[i], adr[i]?adr[i] - image_offset:0, name[i]); } }#endif return res;}static int ndis_open(struct net_device *dev){ DBGTRACE("%s\n", __FUNCTION__); return 0;}static int ndis_close(struct net_device *dev){ DBGTRACE("%s\n", __FUNCTION__); return 0;}static struct net_device_stats *ndis_get_stats(struct net_device *dev){ struct ndis_handle *handle = dev->priv; struct net_device_stats *stats = &handle->stats; unsigned int x; if(!query_int(handle, NDIS_OID_STAT_TX_OK, &x)) stats->tx_packets = x; if(!query_int(handle, NDIS_OID_STAT_RX_OK, &x)) stats->rx_packets = x; if(!query_int(handle, NDIS_OID_STAT_TX_ERROR, &x)) stats->tx_errors = x; if(!query_int(handle, NDIS_OID_STAT_RX_ERROR, &x)) stats->rx_errors = x; return stats;}static struct iw_statistics *ndis_get_wireless_stats(struct net_device *dev){ struct ndis_handle *handle = dev->priv; struct iw_statistics *stats = &handle->wireless_stats; int x; if(!query_int(handle, NDIS_OID_RSSI, &x)) stats->qual.level = x; return stats;}static int ndis_ioctl(struct net_device *dev, struct ifreq *rq, int cmd){ int rc = -ENODEV; return rc;}/* * This can probably be done a lot more effective (no copy of data needed). * * */static int ndis_start_xmit(struct sk_buff *skb, struct net_device *dev){ struct ndis_handle *handle = dev->priv; struct ndis_buffer *buffer; struct ndis_packet *packet; char *data = kmalloc(skb->len, GFP_ATOMIC); if(!data) { return 0; } buffer = kmalloc(sizeof(struct ndis_buffer), GFP_ATOMIC); if(!buffer) { kfree(data); return 0; } packet = kmalloc(sizeof(struct ndis_packet), GFP_ATOMIC); if(!packet) { kfree(data); kfree(buffer); return 0; } memset(packet, 0, sizeof(*packet));#ifdef DEBUG { int i = 0; /* Poision extra packet info */ int *x = (int*) &packet->ext1; for(i = 0; i <= 12; i++) { x[i] = i; } }#endif if(handle->use_scatter_gather) { packet->dataphys = pci_map_single(handle->pci_dev, data, skb->len, PCI_DMA_TODEVICE); packet->scatterlist.len = 1; packet->scatterlist.entry.physlo = packet->dataphys; packet->scatterlist.entry.physhi = 0; packet->scatterlist.entry.len = skb->len; packet->scatter_gather_ext = &packet->scatterlist; } packet->oob_offset = (int)(&packet->timesent1) - (int)packet; buffer->data = data; buffer->next = 0; buffer->len = skb->len; packet->nr_pages = 1; packet->len = buffer->len; packet->count = 1; packet->valid_counts = 1; packet->buffer_head = buffer; packet->buffer_tail = buffer; //DBGTRACE("Buffer: %08x, data %08x, len %d\n", (int)buffer, (int)buffer->data, (int)buffer->len); skb_copy_and_csum_dev(skb, data); dev_kfree_skb(skb);// DBGTRACE("Calling send_packets at %08x rva(%08x). sp:%08x\n", (int)handle->miniport_char.send_packets, (int)handle->miniport_char.send_packets - image_offset, getSp()); if(handle->driver->miniport_char.send_packets) { struct ndis_packet *packets[1]; packets[0] = packet; handle->driver->miniport_char.send_packets(handle->adapter_ctx, &packets[0], 1); } else if(handle->driver->miniport_char.send) { int res = handle->driver->miniport_char.send(handle->adapter_ctx, packet, 0); if(res == NDIS_STATUS_PENDING) { return 0; } ndis_sendpacket_done(handle, packet); return 0; } else { DBGTRACE("%s: No send handler\n", __FUNCTION__); } return 0;}/* * Free and unmap a packet created in xmit */void ndis_sendpacket_done(struct ndis_handle *handle, struct ndis_packet *packet){ if(packet->dataphys) { pci_unmap_single(handle->pci_dev, packet->dataphys, packet->len, PCI_DMA_TODEVICE); } kfree(packet->buffer_head->data); kfree(packet->buffer_head); kfree(packet);}static int setup_dev(struct net_device *dev){ struct ndis_handle *handle = dev->priv; unsigned char mac[6]; unsigned int written; unsigned int needed; unsigned int res; int i; DBGTRACE("%s: Querying for mac\n", __FUNCTION__); res = doquery(handle, 0x01010102, &mac[0], sizeof(mac), &written, &needed); DBGTRACE("mac:%02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -