am930mgr.c
来自「Linux Wireless LAN Project 的目标是开发一个完整的」· C语言 代码 · 共 2,470 行 · 第 1/5 页
C
2,470 行
am930shim_pballoc_p80211( pb, WLAN_REASSOCRESP_FR_MAXLEN); if (pb->p80211hostbuf == NULL ) { am930shim_pbfree(pb); pb = NULL; } else { /* finish buffer setup */ pb->p80211_payloadlen += 4; /* length fix again, see pballoc_p80211 */ /* Setup the reply structure. */ reply.buf = pb->p80211buf; reply.len = WLAN_REASSOCRESP_FR_MAXLEN; wlan_mgmt_encode_reassocresp(&reply); /* Setup the header */ reply.hdr->a3.fc = host2ieee16( WLAN_SET_FC_FTYPE(WLAN_FTYPE_MGMT) | WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_REASSOCRESP)); memcpy( reply.hdr->a3.a1, daddr, WLAN_ADDR_LEN); memcpy( reply.hdr->a3.a2, mgr->hw->addr, WLAN_ADDR_LEN); memcpy( reply.hdr->a3.a3, mgr->curr_bssid, WLAN_BSSID_LEN); /* Set the status and aid */ *(reply.cap_info) = host2ieee16(capinfo); *(reply.status) = host2ieee16(status); *(reply.aid) = host2ieee16(aid); /* Copy the rate set */ reply.supp_rates = (wlan_ie_supp_rates_t*)(reply.buf + reply.len); reply.len += rates->len + WLAN_IEHDR_LEN; memcpy(reply.supp_rates, rates, rates->len + WLAN_IEHDR_LEN); /* Adjust the length fields */ if ( pb != NULL ) { pb->p80211frmlen = reply.len; pb->p80211_payloadlen = reply.len - WLAN_HDR_A3_LEN; } } } DBFEXIT; return pb;}/*----------------------------------------------------------------* am930mgr_reassocreq_rx** Handle incoming reassociation request frames.* NOTE: This is basically a cut-n-paste of the assocreq_rx * function (bad Mark, bad, bad). If you change anything* here it should probably be changed in assocreq.** Arguments:* rxpb packet buffer containing assocreq frame* stats receive statitistics for assocreq frame** returns: nothing for now----------------------------------------------------------------*/void am930mgr_reassocreq_rx( am930mgr_t *mgr, wlan_pb_t *rxpb, am930rxstats_t *stats){ wlan_fr_reassocreq_t f; wlan_stable_item_t *sta; wlan_pb_t *pb; DBFENTER; /* decode the frame */ f.len = rxpb->p80211buflen - WLAN_CRC_LEN; f.buf = rxpb->p80211buf; wlan_mgmt_decode_reassocreq(&f); /* Check for class2 error */ sta = am930mgr_stable_lookup( mgr, f.hdr->a3.a2); if ( sta == NULL || !(sta->sta.info & WLAN_STA_INFO_AUTH) ) { pb = am930mgr_mkfrm_deauth( mgr, f.hdr->a3.a2, WLAN_MGMT_REASON_CLASS2_NONAUTH); if ( pb != NULL ) { am930mac_txmac( mgr->mac, pb); } return; } /* Check to make sure we're the SS the station says we are */ /* assume bad BSSID would be rejected by rx filter */ if ( memcmp( f.ssid->ssid, mgr->curr_ssid + WLAN_IEHDR_LEN, mgr->curr_ssid[1]) != 0 ) { pb = am930mgr_mkfrm_reassocresp( mgr, f.hdr->a3.a2, am930mac_mk_capinfo(mgr->mac), WLAN_MGMT_STATUS_ASSOC_DENIED_UNSPEC, 0, /* AID */ (wlan_ie_supp_rates_t*)mgr->mac->oprates ); if ( pb != NULL ) { am930mac_txmac( mgr->mac, pb); } return; } /* Capability Info check */ /* condition 1: is it not asking for an ESS? */ /* condition 2: is it asking for polling? (we don't support it) */ /* condition 3: is it asking for WEP and our wep keys aren't set? */ if ( (WLAN_GET_MGMT_CAP_INFO_ESS(ieee2host16(*f.cap_info)) == 0) || ((WLAN_GET_MGMT_CAP_INFO_CFPOLLABLE(ieee2host16(*f.cap_info)) == 1) && (WLAN_GET_MGMT_CAP_INFO_CFPOLLREQ(ieee2host16(*f.cap_info)) == 0)) || ((WLAN_GET_MGMT_CAP_INFO_PRIVACY(ieee2host16(*f.cap_info)) == 1) && (mgr->mac->privacy_invoked == 0)) ) { pb = am930mgr_mkfrm_reassocresp( mgr, f.hdr->a3.a2, am930mac_mk_capinfo(mgr->mac), WLAN_MGMT_STATUS_CAPS_UNSUPPORTED, 0, /* AID */ (wlan_ie_supp_rates_t*)mgr->mac->oprates ); if ( pb != NULL ) { am930mac_txmac( mgr->mac, pb); } return; } /* Basic Rate Check */ if ( !am930mgr_rates_basicissubset( mgr, (wlan_ie_supp_rates_t*)mgr->mac->oprates, f.supp_rates) ) { /* mismatch in basic rates */ pb = am930mgr_mkfrm_reassocresp( mgr, f.hdr->a3.a2, am930mac_mk_capinfo(mgr->mac), WLAN_MGMT_STATUS_ASSOC_DENIED_RATES, 0, /* AID */ (wlan_ie_supp_rates_t*)mgr->mac->oprates ); if ( pb != NULL ) { am930mac_txmac( mgr->mac, pb); } return; } /* Made it! we're now ready to handle success! */ if ( (sta->sta.listen_int = ieee2host16(*f.listen_int)) ) { sta->sta.info |= WLAN_STA_INFO_PSMODE; } if ( WLAN_GET_MGMT_CAP_INFO_PRIVACY(ieee2host16(*f.cap_info)) ) { sta->sta.info |= WLAN_STA_INFO_WEPON; } sta->sta.rate = sta->sta.max_rate = am930mgr_rates_max(f.supp_rates); sta->sta.info |= WLAN_STA_INFO_ASSOC; pb = am930mgr_mkfrm_reassocresp( mgr, f.hdr->a3.a2, am930mac_mk_capinfo(mgr->mac), WLAN_MGMT_STATUS_SUCCESS, sta->sta.aid | BIT14 | BIT15, (wlan_ie_supp_rates_t*)mgr->mac->oprates ); if ( pb != NULL ) { am930mac_txmac( mgr->mac, pb); } DBFEXIT; return;}/*----------------------------------------------------------------* am930mgr_proberesp_rx** Handles probe response management frames. This function shold* only be called when we are in an active scanning state.* Otherwise the frame is ignored.* When the probe response is received, we check to see if the* bss owning the responder is a "known bss". If not, we add this* bss to the list.** returns: nothing----------------------------------------------------------------*/void am930mgr_proberesp_rx( am930mgr_t *mgr, wlan_pb_t *rxpb, am930rxstats_t *stats){ knownbss_t *bssptr; wlan_fr_proberesp_t f; DBFENTER; /* decode the frame */ f.len = rxpb->p80211buflen - WLAN_CRC_LEN; f.buf = rxpb->p80211buf; wlan_mgmt_decode_proberesp(&f); /* search for the bss */ bssptr = mgr->bsslist; while ( bssptr != NULL ) { if ( memcmp(bssptr->bssid, f.hdr->a3.a3, WLAN_BSSID_LEN) == 0 ) break; bssptr = bssptr->next; } if ( bssptr == NULL ) { /* it's not in the list, add it */ bssptr = kmalloc( sizeof( knownbss_t ), GFP_ATOMIC ); if ( bssptr != NULL ) /* handle failure by just dropping the Presp. */ { memset( bssptr, 0, sizeof(knownbss_t) ); /* save the bss info */ memcpy( bssptr->bssid, f.hdr->a3.a3, WLAN_BSSID_LEN); memcpy( bssptr->bss_timestamp, f.ts, sizeof(UINT64)); bssptr->bcn_int = ieee2host16(*f.bcn_int); bssptr->cap_info = ieee2host16(*f.cap_info); memcpy( bssptr->ssid, f.ssid, f.ssid->len + WLAN_IEHDR_LEN); bssptr->ssid[f.ssid->len + WLAN_IEHDR_LEN] = '\0';WLAN_LOG_DEBUG1(2, "proberesp: ssid=%s\n", bssptr->ssid + WLAN_IEHDR_LEN); bssptr->channel = f.ds_parms->curr_ch; bssptr->rate = 20; /*TODO: parse the supp rates IE */ bssptr->sutro_reftime = amd2host32(stats->local_time); // am930 specific bssptr->ttl = 0; bssptr->next = mgr->bsslist; mgr->bsslist = bssptr; } } else { /* the bss is in the list, update ttl */ } DBFEXIT; return;}/*----------------------------------------------------------------* am930mgr_probereq_rx** Handles probe request management frames.** returns: nothing----------------------------------------------------------------*/void am930mgr_probereq_rx( am930mgr_t *mgr, wlan_pb_t *rxpb, am930rxstats_t *stats){ DBFENTER; DBFEXIT; return;}/*----------------------------------------------------------------* am930mgr_prstatus** Log a warning message based on the contents of the Status* Code field of an 802.11 management frame. Defines are in* p80211mgmt.h and are derived from 802.11-1997 pp 54.** returns: nothing----------------------------------------------------------------*/void am930mgr_prstatus(am930mgr_t *mgr, UINT16 status ){ switch( status ) { case WLAN_MGMT_STATUS_UNSPEC_FAILURE: WLAN_LOG_ERROR0("Status code == Unspecified error.\n"); break; case WLAN_MGMT_STATUS_CAPS_UNSUPPORTED: WLAN_LOG_ERROR0("Status code == Can't support all requested capabilities.\n"); break; case WLAN_MGMT_STATUS_REASSOC_NO_ASSOC: WLAN_LOG_ERROR0("Status code == Reassoc denied, can't confirm original Assoc.\n"); break; case WLAN_MGMT_STATUS_ASSOC_DENIED_UNSPEC: WLAN_LOG_ERROR0("Status code == Assoc denied, because we don't feel like it.\n"); break; case WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG: WLAN_LOG_ERROR0("Status code == Peer doesn't support authen algorithm.\n"); break; case WLAN_MGMT_STATUS_RX_AUTH_NOSEQ: WLAN_LOG_ERROR0("Status code == Authen frame received out of sequence.\n"); break; case WLAN_MGMT_STATUS_CHALLENGE_FAIL: WLAN_LOG_ERROR0("Status code == Authen rejected, challenge failure.\n"); break; case WLAN_MGMT_STATUS_AUTH_TIMEOUT: WLAN_LOG_ERROR0("Status code == Authen rejected, timeout waiting for next frame.\n"); break; case WLAN_MGMT_STATUS_ASSOC_DENIED_BUSY: WLAN_LOG_ERROR0("Status code == Assoc denied, AP too busy.\n"); break; case WLAN_MGMT_STATUS_ASSOC_DENIED_RATES: WLAN_LOG_ERROR0("Status code == Assoc denied, we haven't enough basic rates.\n"); break; default: WLAN_LOG_ERROR1("Unknown status code %d.\n", status); break; }}/*----------------------------------------------------------------* am930mgr_rates_max** Returns the maximum rate (basic or not) in information element r.** Arguments:* r an information element containing rates** returns: * the value of the maximum rate.----------------------------------------------------------------*/UINT8 am930mgr_rates_max(wlan_ie_supp_rates_t *r){ int i; UINT8 maxrate = 0; DBFENTER; for ( i=0; i < r->len; i++) { maxrate = maxrate > r->rates[i] ? maxrate : r->rates[i]; } DBFEXIT; return maxrate;}/*----------------------------------------------------------------* am930mgr_rates_basicissubset** Checks if the basic rates in information element r2 are* a subset (or the same as) the rates in r1.** Arguments:* r1 an information element containing the rates we're* checking against.* r2 an information element containing the rates we're* checking.** returns: * true if the basic rates in r2 are a subset of the basic* rates in r1.----------------------------------------------------------------*/int am930mgr_rates_basicissubset( am930mgr_t *mgr, wlan_ie_supp_rates_t *r1, wlan_ie_supp_rates_t *r2){ int i; int j; int badrates = 0; int foundrate = 0; DBFENTER; /* for each rate in r2 */ for ( i=0; i < r2->len; i++) { if ( WLAN_MGMT_ISBASICRATE(r2->rates[i]) ) { /* find matching rate in r1 */ foundrate = 0; for ( j=0; j < r1->len; j++) { if ( WLAN_MGMT_GET_RATE(r2->rates[i]) == WLAN_MGMT_GET_RATE(r1->rates[j]) ) { foundrate = 1; if (!WLAN_MGMT_ISBASICRATE(r1->rates[j])) { badrates = 1; break; } } } if ( !foundrate ) { badrates = 1; break; } } } DBFEXIT; return !badrates;}/*----------------------------------------------------------------* am930mgr_rxmgmt** Entry point for the reception and handling of 802.11 management* frames. Makes a determination of the frame type and then calls* the appropriate function.** returns: zero on success, non-zero on failure----------------------------------------------------------------*/void am930mgr_rxmgmt( am930mgr_t *mgr, wlan_pb_t *rxpb, am930rxstats_t *stats){ DBFENTER; switch( WLAN_GET_FC_FSTYPE(ieee2host16(rxpb->p80211_hdr->a3.fc)) ) { case WLAN_FSTYPE_ASSOCREQ: WLAN_LOG_DEBUG0(3, "rx assocreq\n"); am930mgr_assocreq_rx( mgr, rxpb, stats); break; case WLAN_FSTYPE_ASSOCRESP: WLAN_LOG_DEBUG0(3, "rx assocresp\n"); am930mgr_assocresp_rx( mgr, rxpb, stats); break; case WLAN_FSTYPE_REASSOCREQ: WLAN_LOG_DEBUG0(3, "rx reassocreq\n"); am930mgr_reassocreq_rx( mgr, rxpb, stats); break; case WLAN_FSTYPE_REASSOCRESP: WLAN_LOG_DEBUG0(3, "rx reassocresp\n"); break; case WLAN_FSTYPE_PROBEREQ: WLAN_LOG_DEBUG0(3, "rx probereq\n"); /* doesn't do anything right now am930mgr_probereq_rx( mgr, rxpb, stats); */ break; case WLAN_FSTYPE_PROBERESP: WLAN_LOG_DEBUG0(3, "rx proberesp\n"); am930mgr_proberesp_rx( mgr, rxpb, stats); break; case WLAN_FSTYPE_BEACON: WLAN_LOG_DEBUG0(3, "rx beacon\n"); /* doesn't do anything right now am930mgr_beacon_rx( mgr, rxpb, stats); */ break; case WLAN_FSTYPE_ATIM: WLAN_LOG_DEBUG0(3, "rx atim\n"); break; case WLAN_FSTYPE_DISASSOC: WLAN_LOG_DEBUG0(3, "rx disassoc\n"); break; case WLAN_FSTYPE_AUTHEN: WLAN_LOG_DEBUG0(3, "rx authen\n"); am930mgr_authen_rx( mgr, rxpb, stats); break; case WLAN_FSTYPE_DEAUTHEN: WLAN_LOG_DEBUG0(3, "rx deauthen\n"); break; default: WLAN_LOG_DEBUG0(3, "rx unknown mgmt\n"); } am930shim_pbfree( rxpb ); kfree_s(stats, sizeof(am930rxstats_t)); DBFEXIT; return;}/*----------------------------------------------------------------* am930mgr_scanbegin** Set up scanning managed by the mgr object. This function* begins the scanning of a sequence of channels. We call the* hw scan method registering the callback so we can setup the* scan the of the next channel. We pick up scan results via the* rx_mgmt method via probe response and beacon frames.* scantype: 0: active 1: passive* bsstype: BIT0: independent BIT1: infrastructure* timech is in Kus** returns: zero on success, * 1 - already scanning* 2 - scan command failed----------------------------------------------------------------*/UINT32 am930mgr_scanbegin( am930mgr_t *mg
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?