📄 ieee80211_module.c
字号:
} void ieee80211_associate_abort_(unsigned long dev){ ieee80211_associate_abort((struct ieee80211_device *) dev);}void ieee80211_associate_abort(struct ieee80211_device *ieee){ ieee->associate_seq++; ieee->link_state=WLAN_LINK_NONE; ieee80211_r8180_flush_scan(ieee); if(ieee->associate_state == ASSOC_AUTH){ IEEE80211DMESG("Authentication failed"); ieee->ieee_stats.aut_noresp++; }else{ IEEE80211DMESG("Association failed"); ieee->ieee_stats.ass_noresp++; } ieee->func->start_scan(ieee->dev); return; }void ieee80211_associate_step2(struct ieee80211_device *ieee){ struct sk_buff* skb; struct ieee80211_beacon *beacon = ieee->ass_beacon; del_timer_sync(&ieee->associate_timer); IEEE80211DMESG("Sending association request"); ieee->ieee_stats.tx_ass++; skb=ieee80211_association_req(beacon,ieee); ieee->func->tx_80211(skb,ieee->dev); ieee->associate_timer.expires = jiffies + (HZ / 2); add_timer(&ieee->associate_timer); }void ieee80211_probe_hidden(struct ieee80211_device *ieee){ struct sk_buff *skb; //IEEE80211DMESG("Sending Probe Request."); skb = ieee80211_probe_req(ieee); ieee->func->tx_80211(skb, ieee->dev); ieee->ieee_stats.tx_probe_rq++;}void ieee80211_associate_complete(struct ieee80211_device *ieee){ struct ieee80211_beacon *beacon = ieee->ass_beacon; del_timer_sync(&ieee->associate_timer); ieee->seq_ctrl=0; ieee->link_state=WLAN_LINK_ASSOCIATED; IEEE80211DMESG("Successfully associated"); ieee->func->associate(ieee->dev,beacon); ieee->func->data_poll_hard_resume(ieee->dev);}void ieee80211_r8180_set_master_essid(struct ieee80211_device *ieee,char* essid, int len){ if(ieee->master_essid) kfree(ieee->master_essid); ieee->master_essid = kmalloc(len+1,GFP_KERNEL); strncpy(ieee->master_essid, essid, len); ieee->master_essid[len] = '\0';}inline short is_broadcast(u8 *adr){ static u8 ff[] = { 0xff,0xff,0xff,0xff,0xff,0xff}; return (0 == memcmp(ff,adr,ETH_ALEN));}inline short is_multicast(u8 *adr){ //FIXME: STUB return 0;}short is_in_htable(struct ieee80211_device *ieee,u8 *adr,struct mac_htable_t *htable[]){ struct mac_htable_t *list; for (list = htable[adr[ETH_ALEN - 1] % MAC_HTABLE_ENTRY]; list!=NULL; list = list->next){ if(0==memcmp(list->adr,adr,ETH_ALEN)) return 1; } return 0; }short add_htable(struct ieee80211_device *ieee,u8 *adr,struct mac_htable_t *htable[]){ struct mac_htable_t *list; list = htable[adr[ETH_ALEN - 1] % MAC_HTABLE_ENTRY];// IEEE80211DMESG("inserting "MACSTR" to %x table",MAC2STR(adr),htable); if(list == NULL){// IEEE80211DMESG("list was null"); list = kmalloc(sizeof(struct mac_htable_t),GFP_ATOMIC); list->next = NULL; list->time = jiffies; memcpy(list->adr,adr,ETH_ALEN); htable[adr[ETH_ALEN - 1] % MAC_HTABLE_ENTRY] = list; return 0; } while(list!=NULL){ if(0==memcmp(list->adr,adr,ETH_ALEN)){ list->time = jiffies; return -1; } if(list->next == NULL) break; list = list->next; } list->next = kmalloc(sizeof(struct mac_htable_t),GFP_ATOMIC); list->next->next = NULL; list->next->time = jiffies; memcpy(list->next->adr,adr,ETH_ALEN); return 0;}inline short is_associated(struct ieee80211_device *ieee,u8 *adr){ return is_in_htable(ieee,adr,ieee->assoc_htable);}inline short is_bridged(struct ieee80211_device *ieee,u8 *adr){ return is_in_htable(ieee,adr,ieee->bridge_htable);}inline short add_associate(struct ieee80211_device *ieee,u8 *adr){ return add_htable(ieee,adr,ieee->assoc_htable);}inline short add_bridged(struct ieee80211_device *ieee,u8 *adr){ return add_htable(ieee,adr,ieee->bridge_htable);}void init_htables(struct ieee80211_device *ieee){ int i; for (i=0; i<MAC_HTABLE_ENTRY; i++){ ieee->assoc_htable[i] = NULL; } for (i=0; i<MAC_HTABLE_ENTRY; i++){ ieee->bridge_htable[i] = NULL; } }struct ieee80211_device *ieee80211_r8180_alloc(struct net_device *dev, void *priv){ struct ieee80211_device *ieee = kmalloc( sizeof(struct ieee80211_device), GFP_KERNEL); if (ieee == NULL) return NULL; memset(ieee, 0, sizeof(*ieee)); ieee->dev = dev; ieee->priv = priv;#ifndef CONFIG_IEEE80211_NOWEP /* Default to enabling full open WEP with host based encrypt/decrypt */ ieee->open_wep = 1; ieee->host_encrypt = 1; ieee->host_decrypt = 1; ieee->queue_stop=1; ieee->tx_pending.txb=NULL; INIT_LIST_HEAD(&ieee->crypt_deinit_list); init_timer(&ieee->crypt_deinit_timer); ieee->crypt_deinit_timer.data = (unsigned long)ieee; ieee->crypt_deinit_timer.function = ieee80211_r8180_crypt_deinit_handler; #else ieee->open_wep = 1; ieee->host_encrypt = 0; ieee->host_decrypt = 0;#endif ieee->ieee_stats.aut_noresp=0; ieee->ieee_stats.ass_noresp=0; ieee->ieee_stats.tx_aut=0; ieee->ieee_stats.tx_ass=0; ieee->ieee_stats.rx_ass_ok=0; ieee->ieee_stats.rx_aut_ok=0; ieee->ieee_stats.rx_aut_err=0; ieee->ieee_stats.rx_ass_err=0; ieee->ieee_stats.rx_assoc_rq=0; ieee->ieee_stats.rx_auth_rq=0; ieee->ieee_stats.swtxstop=0; ieee->ieee_stats.swtxawake=0; ieee->ieee_stats.reassoc=0; memset(ieee->ap,0, ETH_ALEN); /* Default fragmentation threshold is maximum payload size */ ieee->fts = 2342; ieee->master_essid = NULL; spin_lock_init(&ieee->lock); spin_lock_init(&ieee->irq_lock); ieee->assoc_id =0; INIT_LIST_HEAD(&ieee->beacons); init_timer(&ieee->associate_timer); ieee->associate_timer.data = (unsigned long)ieee; ieee->associate_timer.function = ieee80211_associate_abort_;/* init_waitqueue_head(&ieee->assoc_queue); ieee->workqueue = create_workqueue(DRV_NAME); INIT_WORK(&ieee->associate_tasklet,(void(*)(void*)) ieee80211_associate_tasklet,ieee);*/ init_htables(ieee); return ieee;}void ieee80211_r8180_free(struct ieee80211_device *ieee){#ifndef CONFIG_IEEE80211_NOWEP int i;#endif //unsigned long flags; if (!ieee) return; #ifndef CONFIG_IEEE80211_NOWEP // PR: FIXME: added this "if" because hostap had it, is it really needed? if (timer_pending(&ieee->crypt_deinit_timer)) del_timer(&ieee->crypt_deinit_timer); ieee80211_r8180_crypt_deinit_entries(ieee, 1); for (i = 0; i < WEP_KEYS; i++) { struct ieee80211_crypt_data *crypt = ieee->crypt[i]; if (crypt) { if (crypt->ops) crypt->ops->deinit(crypt->priv); kfree(crypt); ieee->crypt[i] = NULL; } }#endif ieee80211_r8180_flush_scan(ieee); if (timer_pending(&ieee->associate_timer)) del_timer(&ieee->associate_timer); kfree(ieee);}void ieee80211_r8180_flush_scan(struct ieee80211_device *ieee){ struct list_head *b,*delprev,*prev,*next; delprev = NULL; list_for_each(b,&ieee->beacons){ if (delprev){ kfree(list_entry(delprev,struct ieee80211_beacon,list)); delprev=NULL; } //beacon=list_entry(b,struct ieee80211_beacon,list); prev = b->prev; next = b->next; next->prev = prev; prev->next = next; delprev=b; } if (delprev){ kfree(list_entry(delprev,struct ieee80211_beacon,list)); delprev=NULL; } }void ieee80211_new_net(struct ieee80211_device *ieee, struct ieee80211_beacon *beacon){ u8 zero[] = {0,0,0,0,0,0}; short apset,ssidset,ssidbroad,apmatch,ssidmatch; if(ieee->iw_mode == IW_MODE_INFRA){ /* if the user specified the AP MAC, we need also the essid * This could be obtained by beacons or, if the network does not * broadcast it, it can be put manually. */ apset = (memcmp(ieee->ap, zero,ETH_ALEN)!=0 ); ssidset = ieee->ssid[0] != '\0'; ssidbroad = !(beacon->ssid_len == 0 || beacon->ssid[0]== '\0'); apmatch = (memcmp(ieee->ap, beacon->bssid,ETH_ALEN)==0); ssidmatch = (0==strncmp(ieee->ssid, beacon->ssid,beacon->ssid_len)); if( /* if the user set the AP check if match. * if the network does not broadcast essid we check the user supplyed ANY essid * if the network does broadcast and the user does not set essid it is OK * if the network does broadcast and the user did set essid chech if essid match */ ( apset && apmatch && ((ssidset && ssidbroad && ssidmatch) || (ssidbroad && !ssidset) || (!ssidbroad && ssidset)) ) || /* if the ap is not set, check that the user set the bssid * and the network does bradcast and that those two bssid matches */ (!apset && ssidset && ssidbroad && ssidmatch) ){ IEEE80211DMESG( "Associating with %s",ieee->ssid); ieee->ass_beacon = beacon; /* if the essid is hidden replace it with the * essid provided by the user. */ if(!ssidbroad){ strcpy(ieee->ass_beacon->ssid, ieee->ssid); ieee->ass_beacon->ssid_len = strlen(ieee->ssid); } /* if the user provided only the AP mac but not the essid then * copy it from the broadcasted to the nic current essid */ if(apset && !ssidset) strncpy(ieee->ssid, beacon->ssid, beacon->ssid_len); ieee->link_state=WLAN_LINK_ASSOCIATING; ieee80211_associate_step1(ieee); } }else if (ieee->iw_mode == IW_MODE_ADHOC){ if(beacon->ssid_len== strlen(ieee->master_essid) && 0==memcmp(ieee->master_essid, beacon->ssid,beacon->ssid_len)){ ieee->beacon_interval = beacon->interval; memcpy(ieee->beacon_cell_ssid, beacon->bssid, ETH_ALEN); /* at the very last we check if the user has * forced manually the channel while we was * scanning */ if(ieee->link_state == WLAN_LINK_ASSOCIATED) return; ieee->link_state = WLAN_LINK_ASSOCIATED; ieee->master_chan = beacon->channel; } } //kfree(beacon);}static int __init ieee80211_r8180_init(void){ printk(KERN_INFO MODULE_NAME ": loading with WEP "#ifdef CONFIG_IEEE80211_NOWEP "disabled"#else "enabled"#endif ".\n"); return 0;}static void __exit ieee80211_r8180_deinit(void){ printk(KERN_INFO MODULE_NAME ": unloading.\n");}EXPORT_SYMBOL(ieee80211_r8180_alloc);EXPORT_SYMBOL(ieee80211_r8180_free);EXPORT_SYMBOL(ieee80211_r8180_set_master_essid);EXPORT_SYMBOL(ieee80211_r8180_flush_scan);EXPORT_SYMBOL(ieee80211_probe_hidden);module_init(ieee80211_r8180_init);module_exit(ieee80211_r8180_deinit);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -